X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ospfd%2Fospf_vty.c;h=43b7de552ad1c1addd4a2442fb19b8c62ca9eeb7;hb=2e1ea892220dccb8a4c72e438cb3bbd4cac22b2b;hp=7d72487686a40d0213068456a38d9ae81a5eed55;hpb=58e0011dc53692d5c4cf94be1e7274addb4bcb31;p=mirror_frr.git diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 7d7248768..262f80546 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* OSPF VTY interface. * Copyright (C) 2005 6WIND * 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 @@ -184,9 +169,7 @@ static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty, } } -#ifndef VTYSH_EXTRACT_PL #include "ospfd/ospf_vty_clippy.c" -#endif DEFUN_NOSH (router_ospf, router_ospf_cmd, @@ -3055,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, @@ -3290,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) @@ -4872,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; @@ -4893,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"); @@ -4919,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 ] 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; @@ -4996,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, @@ -5140,19 +5112,36 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, json_object_string_add(json_neigh, "areaId", ospf_area_desc_string(oi->area)); json_object_string_add(json_neigh, "ifaceName", oi->ifp->name); - } else - vty_out(vty, " In the area %s via interface %s\n", + if (oi->address) + json_object_string_addf(json_neigh, "localIfaceAddress", + "%pI4", + &oi->address->u.prefix4); + } else { + vty_out(vty, " In the area %s via interface %s", ospf_area_desc_string(oi->area), oi->ifp->name); + if (oi->address) + vty_out(vty, " local interface IP %pI4\n", + &oi->address->u.prefix4); + else + vty_out(vty, "\n"); + } /* Show neighbor priority and state. */ ospf_nbr_ism_state_message(nbr, neigh_state, sizeof(neigh_state)); if (use_json) { json_object_int_add(json_neigh, "nbrPriority", nbr->priority); json_object_string_add(json_neigh, "nbrState", neigh_state); - } else - vty_out(vty, " Neighbor priority is %d, State is %s,", - nbr->priority, neigh_state); - + json_object_string_add(json_neigh, "role", + lookup_msg(ospf_ism_state_msg, + ospf_nbr_ism_state(nbr), + NULL)); + } else { + vty_out(vty, + " Neighbor priority is %d, State is %s, Role is %s,", + nbr->priority, neigh_state, + lookup_msg(ospf_ism_state_msg, ospf_nbr_ism_state(nbr), + NULL)); + } /* Show state changes. */ if (use_json) json_object_int_add(json_neigh, "stateChangeCounter", @@ -5386,7 +5375,8 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, struct in_addr *router_id, bool use_json, uint8_t use_vrf, - bool is_detail) + bool is_detail, + json_object *json_vrf) { struct listnode *node; struct ospf_neighbor *nbr; @@ -5420,6 +5410,14 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, use_json); } + if (json_vrf && use_json) { + json_object_object_add( + json_vrf, + (ospf->vrf_id == VRF_DEFAULT) ? "default" : ospf->name, + json); + return CMD_SUCCESS; + } + if (use_json) vty_json(vty, json); else @@ -5428,23 +5426,50 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, return CMD_SUCCESS; } -DEFPY(show_ip_ospf_neighbor_id, show_ip_ospf_neighbor_id_cmd, - "show ip ospf neighbor A.B.C.D$router_id [detail$detail] [json$json]", - SHOW_STR IP_STR +DEFPY(show_ip_ospf_neighbor_id, + show_ip_ospf_neighbor_id_cmd, + "show ip ospf [vrf NAME$vrf_name] neighbor A.B.C.D$router_id [detail$detail] [json$json]", + SHOW_STR + IP_STR "OSPF information\n" + VRF_CMD_HELP_STR "Neighbor list\n" "Neighbor ID\n" - "Detailed output\n" JSON_STR) + "Detailed output\n" + JSON_STR) { struct ospf *ospf; struct listnode *node; int ret = CMD_SUCCESS; + int inst = 0; - for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { - if (!ospf->oi_running) - continue; - ret = show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, - !!json, 0, !!detail); + if (vrf_name && !strmatch(vrf_name, "all")) { + 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; + } + ret = show_ip_ospf_neighbor_id_common( + vty, ospf, &router_id, !!json, 0, !!detail, NULL); + } else { + 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; + ret = show_ip_ospf_neighbor_id_common( + vty, ospf, &router_id, !!json, 0, !!detail, + json_vrf); + } + if (json) + vty_json(vty, json_vrf); } return ret; @@ -5469,7 +5494,7 @@ DEFPY(show_ip_ospf_instance_neighbor_id, show_ip_ospf_instance_neighbor_id_cmd, return CMD_SUCCESS; return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json, 0, - !!detail); + !!detail, NULL); } static int show_ip_ospf_neighbor_detail_common(struct vty *vty, @@ -5534,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 ] 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 $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; } @@ -5833,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; @@ -5843,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) @@ -5854,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; } @@ -5888,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) @@ -5927,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; @@ -5953,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 */ @@ -5966,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 (lsa == NULL) + return 0; - 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); - } + /* If self option is set, check LSA self flag. */ + if (self == 0 || IS_LSA_SELF(lsa)) { - /* LSA specific part show. */ - switch (lsa->data->type) { - case OSPF_ROUTER_LSA: - rl = (struct router_lsa *)lsa->data; + 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, " %-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 (!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); + 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, " %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, " %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[] = { @@ -6146,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, @@ -6615,14 +6713,17 @@ 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) { + 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); + } } route_unlock_node(start); } @@ -6641,9 +6742,6 @@ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, 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: @@ -6686,6 +6784,7 @@ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, } if (json) { + json_lsa_type = json_object_new_object(); json_object_object_add(json_lsa_type, "areas", json_areas); json_object_object_add(json, @@ -6701,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); } } } @@ -6738,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: @@ -6750,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, @@ -6985,15 +7089,13 @@ static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf, 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) +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 idx_type = 4; - int type, ret; - struct in_addr id, adv_router; + int type; json_object *json_vrf = NULL; if (uj) { @@ -7022,435 +7124,201 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, &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 MaxAge LSAs */ + if (maxage) { 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; + 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); } - show_lsa_detail(vty, ospf, type, &id, &adv_router, - json_vrf); } + return CMD_SUCCESS; } - 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 ] database [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) + /* 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; - ospf_output = true; - ret = show_ip_ospf_database_common( - vty, ospf, idx_vrf ? 2 : 0, argc, argv, - use_vrf, json, uj); + 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 (!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); - return CMD_SUCCESS; + 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); } - 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"); - return CMD_SUCCESS; - } - - ret = show_ip_ospf_database_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); - } - - return ret; -} - -ALIAS (show_ip_ospf_database_max, - show_ip_ospf_database_cmd, - "show ip ospf [vrf ] database [ [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 [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); - - if (uj) - vty_json(vty, json); - - return CMD_SUCCESS; -} - -ALIAS (show_ip_ospf_instance_database_max, - show_ip_ospf_instance_database_cmd, - "show ip ospf (1-65535) database [ [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) - -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; - 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, "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); } /* 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 - 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) - return CMD_WARNING; + 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 ] database [json]", +DEFPY (show_ip_ospf_database, + show_ip_ospf_database_cmd, + "show ip ospf [(1-65535)$instance_id] [vrf $vrf_name] database\ + [<\ + max-age$maxage\ + |self-originate$selforig\ + |<\ + detail$detail\ + |$type_name\ + >\ + [{\ + A.B.C.D$lsid\ + |\ + }]\ + >]\ + [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; - - 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) { - vty_out(vty, - "%% OSPF is not enabled in vrf %s\n", - vrf_name); - return CMD_SUCCESS; - } - - ret = show_ip_ospf_database_type_adv_router_common( - vty, ospf, 2, 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 on vrf default\n"); - return CMD_SUCCESS; - } - - 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); - } - - 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 [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; + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + if (ospf->instance != instance_id) + continue; - if (uj) - json = json_object_new_object(); + if (adv_router_self) + adv_router_p = &ospf->router_id; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (instance != ospf_instance) - return CMD_NOT_MY_INSTANCE; + 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); + } - ospf = ospf_lookup_instance(instance); - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; + if (!ospf_output && !uj) + vty_out(vty, "%% OSPF is not enabled\n"); + } else { + 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 instance not found\n"); + return CMD_SUCCESS; + } + if (adv_router_self) + adv_router_p = &ospf->router_id; - show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv, - 0, json, uj); + ret = (show_ip_ospf_database_common( + vty, ospf, !!maxage, !!selforig, !!detail, type_name, + lsid_p, adv_router_p, use_vrf, json, uj)); + } if (uj) vty_json(vty, json); - return CMD_SUCCESS; + return ret; } DEFUN (ip_ospf_authentication_args, @@ -9412,7 +9280,7 @@ DEFUN (ospf_default_information_originate, idx = 1; /* Get route-map */ if (argv_find(argv, argc, "route-map", &idx)) - rtmap = argv[idx]->arg + 1; + rtmap = argv[idx + 1]->arg; /* To check if user is providing same route map */ if ((!rtmap && !ROUTEMAP_NAME(red)) || @@ -9892,49 +9760,6 @@ DEFPY(no_ospf_gr_helper_enable, return CMD_SUCCESS; } -#if CONFDATE > 20220921 -CPP_NOTICE( - "Time to remove the deprecated \"[no] graceful-restart helper-only\" commands") -#endif - -DEFPY_HIDDEN(ospf_gr_helper_only, ospf_gr_helper_only_cmd, - "graceful-restart helper-only [A.B.C.D]", - "OSPF Graceful Restart\n" - "Enable Helper support\n" - "Advertising router id\n") -{ - VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - struct in_addr addr; - int ret; - - vty_out(vty, - "%% This command is deprecated. Please, use `graceful-restart helper enable` instead.\n"); - - if (argc == 3) { - ret = inet_aton(argv[2]->arg, &addr); - if (!ret) { - vty_out(vty, - "Please specify the valid routerid address.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE); - return CMD_SUCCESS; - } - - ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE); - - return CMD_SUCCESS; -} - -ALIAS_HIDDEN(no_ospf_gr_helper_enable, - no_ospf_gr_helper_only_cmd, - "no graceful-restart helper-only [A.B.C.D]", - NO_STR - "OSPF Graceful Restart\n" - "Disable Helper support\n" - "Advertising router id\n") - DEFPY(ospf_gr_helper_enable_lsacheck, ospf_gr_helper_enable_lsacheck_cmd, "graceful-restart helper strict-lsa-checking", @@ -10237,17 +10062,10 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, json_object_int_add(json_vrf, "supportedGracePeriod", ospf->supported_grace_time); -#if CONFDATE > 20230131 -CPP_NOTICE("Remove JSON object commands with keys starting with capital") -#endif - if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) { - json_object_string_add( - json_vrf, "LastExitReason", - ospf_exit_reason2str(ospf->last_exit_reason)); + if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) json_object_string_add( json_vrf, "lastExitReason", ospf_exit_reason2str(ospf->last_exit_reason)); - } if (ospf->active_restarter_cnt) json_object_int_add(json_vrf, "activeRestarterCnt", @@ -10280,16 +10098,11 @@ CPP_NOTICE("Remove JSON object commands with keys starting with capital") continue; if (uj) { - json_object_object_get_ex(json_vrf, "Neighbors", - &json_neighbors); json_object_object_get_ex(json_vrf, "neighbors", &json_neighbors); if (!json_neighbors) { json_neighbors = json_object_new_object(); - json_object_object_add(json_vrf, - "Neighbors", - json_neighbors); json_object_object_add(json_vrf, "neighbors", json_neighbors); @@ -10574,28 +10387,18 @@ DEFUN (no_ospf_route_aggregation_timer, static void config_write_stub_router(struct vty *vty, struct ospf *ospf) { - struct listnode *ln; - struct ospf_area *area; - if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) vty_out(vty, " max-metric router-lsa on-startup %u\n", ospf->stub_router_startup_time); if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) vty_out(vty, " max-metric router-lsa on-shutdown %u\n", ospf->stub_router_shutdown_time); - for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { - if (CHECK_FLAG(area->stub_router_state, - OSPF_AREA_ADMIN_STUB_ROUTED)) { - vty_out(vty, " max-metric router-lsa administrative\n"); - break; - } - } + if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) + vty_out(vty, " max-metric router-lsa administrative\n"); + return; } -#if CONFDATE > 20230131 -CPP_NOTICE("Remove JSON object commands with keys containing whitespaces") -#endif static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, struct route_table *rt, json_object *json) @@ -10697,12 +10500,6 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, json_object_string_add( json_nexthop, "ip", " "); - json_object_string_add( - json_nexthop, - "directly attached to", - ifindex2ifname( - path->ifindex, - ospf->vrf_id)); json_object_string_add( json_nexthop, "directlyAttachedTo", @@ -10846,12 +10643,6 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, json_object_string_add( json_nexthop, "ip", " "); - json_object_string_add( - json_nexthop, - "directly attached to", - ifindex2ifname( - path->ifindex, - ospf->vrf_id)); json_object_string_add( json_nexthop, "directlyAttachedTo", @@ -10978,12 +10769,6 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, json_object_string_add( json_nexthop, "ip", " "); - json_object_string_add( - json_nexthop, - "directly attached to", - ifindex2ifname( - path->ifindex, - ospf->vrf_id)); json_object_string_add( json_nexthop, "directlyAttachedTo", @@ -11135,15 +10920,38 @@ DEFUN (show_ip_ospf_instance_reachable_routers, static int show_ip_ospf_border_routers_common(struct vty *vty, struct ospf *ospf, - uint8_t use_vrf) + uint8_t use_vrf, + json_object *json) { - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + json_object *json_vrf = NULL; + json_object *json_router = NULL; - ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + if (json) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + json_router = json_object_new_object(); + } + + if (ospf->instance) { + if (!json) + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + else + json_object_int_add(json_vrf, "ospfInstance", + ospf->instance); + } + + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); if (ospf->new_table == NULL) { - vty_out(vty, "No OSPF routing information exist\n"); + if (!json) + vty_out(vty, "No OSPF routing information exist\n"); + else { + json_object_free(json_router); + if (use_vrf) + json_object_free(json_vrf); + } return CMD_SUCCESS; } @@ -11151,22 +10959,35 @@ static int show_ip_ospf_border_routers_common(struct vty *vty, show_ip_ospf_route_network (vty, ospf->new_table); */ /* Show Router routes. */ - show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, NULL); + show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, json_router); - vty_out(vty, "\n"); + if (json) { + json_object_object_add(json_vrf, "routers", json_router); + 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); + } + } else { + vty_out(vty, "\n"); + } return CMD_SUCCESS; } -DEFUN (show_ip_ospf_border_routers, +DEFPY (show_ip_ospf_border_routers, show_ip_ospf_border_routers_cmd, - "show ip ospf [vrf ] border-routers", + "show ip ospf [vrf ] border-routers [json]", SHOW_STR IP_STR "OSPF information\n" VRF_CMD_HELP_STR "All VRFs\n" - "Show all the ABR's and ASBR's\n") + "Show all the ABR's and ASBR's\n" + JSON_STR) { struct ospf *ospf = NULL; struct listnode *node = NULL; @@ -11176,6 +10997,11 @@ DEFUN (show_ip_ospf_border_routers, 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); @@ -11191,32 +11017,47 @@ DEFUN (show_ip_ospf_border_routers, ospf_output = true; ret = show_ip_ospf_border_routers_common( - vty, ospf, use_vrf); + vty, ospf, use_vrf, json); } - if (!ospf_output) + if (uj) + vty_json(vty, json); + else if (!ospf_output) vty_out(vty, "%% OSPF is not enabled\n"); + + return ret; } 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) + vty_json(vty, json); + else + vty_out(vty, + "%% OSPF is not enabled in vrf %s\n", + vrf_name); + return CMD_SUCCESS; } - - ret = show_ip_ospf_border_routers_common(vty, ospf, - use_vrf); } } 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) + vty_json(vty, json); + else + vty_out(vty, + "%% OSPF is not enabled in vrf default\n"); + return CMD_SUCCESS; } + } - ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf); + if (ospf) { + ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf, + json); + if (uj) + vty_json(vty, json); } return ret; @@ -11243,7 +11084,7 @@ DEFUN (show_ip_ospf_instance_border_routers, if (!ospf || !ospf->oi_running) return CMD_SUCCESS; - return show_ip_ospf_border_routers_common(vty, ospf, 0); + return show_ip_ospf_border_routers_common(vty, ospf, 0, NULL); } static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf, @@ -11265,7 +11106,12 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf, ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); if (ospf->new_table == NULL) { - vty_out(vty, "No OSPF routing information exist\n"); + if (json) { + if (use_vrf) + json_object_free(json_vrf); + } else { + vty_out(vty, "No OSPF routing information exist\n"); + } return CMD_SUCCESS; } @@ -11633,8 +11479,6 @@ static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf, vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n", ospf->aggr_delay_interval); } else { - json_object_int_add(json_vrf, "aggregation delay interval", - ospf->aggr_delay_interval); json_object_int_add(json_vrf, "aggregationDelayInterval", ospf->aggr_delay_interval); } @@ -11653,37 +11497,17 @@ static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf, json_object_object_add(json_vrf, buf, json_aggr); - - json_object_string_add(json_aggr, - "Summary address", buf); json_object_string_add(json_aggr, "summaryAddress", buf); - - json_object_string_add( - json_aggr, "Metric-type", - (mtype == EXTERNAL_METRIC_TYPE_1) - ? "E1" - : "E2"); json_object_string_add( json_aggr, "metricType", (mtype == EXTERNAL_METRIC_TYPE_1) ? "E1" : "E2"); -#if CONFDATE > 20230131 -CPP_NOTICE("Remove JSON object commands with keys starting with capital") -#endif - json_object_int_add(json_aggr, "Metric", mval); json_object_int_add(json_aggr, "metric", mval); - - json_object_int_add(json_aggr, "Tag", - aggr->tag); json_object_int_add(json_aggr, "tag", aggr->tag); - - json_object_int_add( - json_aggr, "External route count", - OSPF_EXTERNAL_RT_COUNT(aggr)); json_object_int_add( json_aggr, "externalRouteCount", OSPF_EXTERNAL_RT_COUNT(aggr)); @@ -12227,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; @@ -12604,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); @@ -12699,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); @@ -12862,8 +12685,6 @@ static void ospf_vty_zebra_init(void) /*Ospf garcefull restart helper configurations */ install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd); install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd); - install_element(OSPF_NODE, &ospf_gr_helper_only_cmd); - install_element(OSPF_NODE, &no_ospf_gr_helper_only_cmd); install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd); install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd); install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd); @@ -12952,6 +12773,179 @@ DEFUN (clear_ip_ospf_interface, return CMD_SUCCESS; } +DEFPY_HIDDEN(ospf_lsa_refresh_timer, ospf_lsa_refresh_timer_cmd, + "[no$no] ospf lsa-refresh [(120-1800)]$value", + NO_STR OSPF_STR + "OSPF lsa refresh timer\n" + "timer value in seconds\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf) + + if (no) + ospf->lsa_refresh_timer = OSPF_LS_REFRESH_TIME; + else + ospf->lsa_refresh_timer = value; + + return CMD_SUCCESS; +} + +DEFPY_HIDDEN(ospf_maxage_delay_timer, ospf_maxage_delay_timer_cmd, + "[no$no] ospf maxage-delay [(0-60)]$value", + NO_STR OSPF_STR + "OSPF lsa maxage delay timer\n" + "timer value in seconds\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf) + + if (no) + ospf->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; + else + ospf->maxage_delay = value; + + THREAD_OFF(ospf->t_maxage); + OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover, + ospf->maxage_delay); + + 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 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 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); @@ -13109,6 +13103,15 @@ void ospf_vty_init(void) vrf_cmd_init(NULL); + 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();