From 5bec85d971a4ab4252c680d5002c64fa8e78c7d9 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Wed, 18 Jan 2023 12:26:01 -0800 Subject: [PATCH 1/4] ospfd: Added missing fields to "show ip ospf neighbor detail" "role" and "local interface address" fields were missing in "show ip ospf neighbor detail" command. Signed-off-by: Pooja Jagadeesh Doijode --- ospfd/ospf_vty.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 469e9955e9..db5c5c1c1f 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -5138,19 +5138,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", From 6333c54822e964afe723f1e923064079fb330075 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Tue, 7 Feb 2023 14:29:54 -0800 Subject: [PATCH 2/4] lib: Helper function to print empty JSON Introduced a helper function to print empty JSON object. Signed-off-by: Pooja Jagadeesh Doijode --- lib/vty.c | 7 +++++++ lib/vty.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c index 2a0bb9446a..8393f67b6d 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -312,6 +312,13 @@ int vty_json_no_pretty(struct vty *vty, struct json_object *json) return vty_json_helper(vty, json, JSON_C_TO_STRING_NOSLASHESCAPE); } +void vty_json_empty(struct vty *vty) +{ + json_object *json = json_object_new_object(); + + vty_json(vty, json); +} + /* Output current time to the vty. */ void vty_time_print(struct vty *vty, int cr) { diff --git a/lib/vty.h b/lib/vty.h index 45349d91af..70c78f5ae8 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -359,7 +359,7 @@ extern bool vty_set_include(struct vty *vty, const char *regexp); */ extern int vty_json(struct vty *vty, struct json_object *json); extern int vty_json_no_pretty(struct vty *vty, struct json_object *json); - +extern void vty_json_empty(struct vty *vty); /* post fd to be passed to the vtysh client * fd is owned by the VTY code after this and will be closed when done */ From a8e6c2c6d03232678d505588e31004193b8cda23 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Tue, 7 Feb 2023 15:29:31 -0800 Subject: [PATCH 3/4] ospfd: Option to query specific neighbor in VRF Added VRF option to "show ip ospf [vrf NAME] neighbor X.X.X.X [detail] [json]" command so that the user can query information regarding a specific neighbor within a VRF. r1# show ip ospf vrf default neighbor 10.0.255.2 10.0.255.2 1 Full/- 33m10s 9.891s 10.0.3.2 r1-eth1:10.0.3.4 0 0 0 r1# show ip ospf vrf default neighbor 10.0.255.2 json { "10.0.255.2":[ { "priority":1, "state":"Full/-", "nbrPriority":1, "nbrState":"Full/-", "converged":"Full", "role":"DROther", "upTimeInMsec":13877947, "deadTimeMsecs":9498, "routerDeadIntervalTimerDueMsec":9498, "upTime":"3h51m17s", "deadTime":"9.498s", "address":"10.0.3.2", "ifaceAddress":"10.0.3.2", "ifaceName":"r1-eth1:10.0.3.4", "retransmitCounter":0, "linkStateRetransmissionListCounter":0, "requestCounter":0, "linkStateRequestListCounter":0, "dbSummaryCounter":0, "databaseSummaryListCounter":0 } ] } r1# show ip ospf vrf default neighbor 10.0.255.2 detail Neighbor 10.0.255.2, interface address 10.0.3.2 In the area 0.0.0.0 via interface r1-eth1 local interface IP 10.0.3.4 Neighbor priority is 1, State is Full/-, Role is DROther, 5 state changes Most recent state change statistics: Progressive change 3h51m27s ago DR is 0.0.0.0, BDR is 0.0.0.0 Options 2 *|-|-|-|-|-|E|- Dead timer due in 8.458s Database Summary List 0 Link State Request List 0 Link State Retransmission List 0 Thread Inactivity Timer on Thread Database Description Retransmision off Thread Link State Request Retransmission on Thread Link State Update Retransmission on Graceful restart Helper info: Graceful Restart HELPER Status : None r1# show ip ospf vrf default neighbor 10.0.255.2 detail json { "10.0.255.2":[ { "ifaceAddress":"10.0.3.2", "areaId":"0.0.0.0", "ifaceName":"r1-eth1", "localIfaceAddress":"10.0.3.4", "nbrPriority":1, "nbrState":"Full/-", "role":"DROther", "stateChangeCounter":5, "lastPrgrsvChangeMsec":13889856, "routerDesignatedId":"0.0.0.0", "routerDesignatedBackupId":"0.0.0.0", "optionsCounter":2, "optionsList":"*|-|-|-|-|-|E|-", "routerDeadIntervalTimerDueMsec":9715, "databaseSummaryListCounter":0, "linkStateRequestListCounter":0, "linkStateRetransmissionListCounter":0, "threadInactivityTimer":"on", "threadLinkStateRequestRetransmission":"on", "threadLinkStateUpdateRetransmission":"on", "grHelperStatus":"None" } ] } r1# Signed-off-by: Pooja Jagadeesh Doijode --- ospfd/ospf_vty.c | 59 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index db5c5c1c1f..af320ce4a3 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -5401,7 +5401,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; @@ -5435,6 +5436,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 @@ -5443,23 +5452,51 @@ 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; @@ -5484,7 +5521,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, From 2e86198322e22ce2baac2b5058b6595cffb4d5f9 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Wed, 8 Feb 2023 14:34:06 -0800 Subject: [PATCH 4/4] ospfd: Fix "show ip ospf neighbor swp1 detail json" output 1. When OSPF unnumbered neighbor doesn't exist in any VRF, OSPFD prints a bunch of empty JSON objects. Fixed it by adding an outer JSON object with VRF information in it 2. Added "vrf" option to this command so that per VRF unnumbered OSPF neighbor information can be retrieved JSON output: nl1# show ip ospf neighbor swp1 detail json { "default":{ }, "vrf1012":{ }, "vrf1013":{ }, "vrf1014":{ } } nl1# show ip ospf vrf vrf1012 neighbor swp4.2 detail json { "9.9.12.10":[ { "ifaceAddress":"200.254.2.46", "areaId":"0.0.0.0", "ifaceName":"swp4.2", "localIfaceAddress":"200.254.2.45", "nbrPriority":1, "nbrState":"Full", "role":"DR", "stateChangeCounter":6, "lastPrgrsvChangeMsec":1462758, "routerDesignatedId":"200.254.2.46", "routerDesignatedBackupId":"200.254.2.45", "optionsCounter":2, "optionsList":"*|-|-|-|-|-|E|-", "routerDeadIntervalTimerDueMsec":37140, "databaseSummaryListCounter":0, "linkStateRequestListCounter":0, "linkStateRetransmissionListCounter":0, "threadInactivityTimer":"on", "threadLinkStateRequestRetransmission":"on", "threadLinkStateUpdateRetransmission":"on" } ] } nl1# Signed-off-by: Pooja Jagadeesh Doijode --- doc/user/ospfd.rst | 6 +- ospfd/ospf_vty.c | 326 ++++++++++++++++++++++++--------------------- 2 files changed, 174 insertions(+), 158 deletions(-) diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index b69230b99d..ce3648bf6d 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -794,13 +794,13 @@ Showing Information .. clicmd:: show ip ospf neighbor [json] -.. clicmd:: show ip ospf neighbor INTERFACE [json] +.. clicmd:: show ip ospf [vrf ] neighbor INTERFACE [json] .. clicmd:: show ip ospf neighbor detail [json] -.. clicmd:: show ip ospf neighbor A.B.C.D [detail] [json] +.. clicmd:: show ip ospf [vrf ] neighbor A.B.C.D [detail] [json] -.. clicmd:: show ip ospf neighbor INTERFACE detail [json] +.. clicmd:: show ip ospf [vrf ] neighbor INTERFACE detail [json] Display lsa information of LSDB. Json o/p of this command covers base route information diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index af320ce4a3..570e1c8266 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4870,9 +4870,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 +4890,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 +4916,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) +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) { 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) + if (!json) 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) -{ - int idx_number = 3; - int idx_ifname = 5; - struct ospf *ospf; - unsigned short instance = 0; - bool uj = use_json(argc, argv); - - if (!uj) - 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 +4939,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 +5422,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 +5529,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; + json_object *json_vrf = NULL; - OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - - 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 +5822,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 +5832,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 +5850,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 +5884,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 +6000,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 +6021,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 */