ospf6d: Json support added for command "show ipv6 ospf6 interface [json]"

Modify code to add JSON format output in show command
"show ipv6 ospf6 interface" with proper formating

Signed-off-by: Yash Ranjan <ranjany@vmware.com>
This commit is contained in:
github login name 2020-10-08 23:27:37 -07:00 committed by Yash Ranjan
parent 0b75cd0bf3
commit f16ae8cf5d
4 changed files with 272 additions and 85 deletions

View file

@ -174,10 +174,11 @@ Showing OSPF6 information
This command shows LSA database summary. You can specify the type of LSA. This command shows LSA database summary. You can specify the type of LSA.
.. index:: show ipv6 ospf6 interface .. index:: show ipv6 ospf6 interface [json]
.. clicmd:: show ipv6 ospf6 interface .. clicmd:: show ipv6 ospf6 interface [json]
To see OSPF interface configuration like costs. To see OSPF interface configuration like costs. JSON output can be
obtained by appending "json" in the end.
.. index:: show ipv6 ospf6 neighbor [json] .. index:: show ipv6 ospf6 neighbor [json]
.. clicmd:: show ipv6 ospf6 neighbor [json] .. clicmd:: show ipv6 ospf6 neighbor [json]

View file

@ -59,7 +59,7 @@ void ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only,
json_object *json_obj, bool use_json) json_object *json_obj, bool use_json)
{ {
if (param_only) if (param_only)
bfd_show_param(vty, bfd_info, 1, 0, 0, NULL); bfd_show_param(vty, bfd_info, 1, 0, use_json, json_obj);
else else
bfd_show_info(vty, bfd_info, 0, 1, use_json, json_obj); bfd_show_info(vty, bfd_info, 0, 1, use_json, json_obj);
} }

View file

@ -22,6 +22,7 @@
#include "lib/json.h" #include "lib/json.h"
#ifndef OSPF6_BFD_H #ifndef OSPF6_BFD_H
#define OSPF6_BFD_H #define OSPF6_BFD_H
#include "lib/json.h"
extern void ospf6_bfd_init(void); extern void ospf6_bfd_init(void);

View file

@ -43,6 +43,7 @@
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_bfd.h" #include "ospf6_bfd.h"
#include "ospf6_zebra.h" #include "ospf6_zebra.h"
#include "lib/json.h"
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names") DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
DEFINE_QOBJ_TYPE(ospf6_interface) DEFINE_QOBJ_TYPE(ospf6_interface)
@ -904,7 +905,8 @@ static const char *ospf6_iftype_str(uint8_t iftype)
} }
/* show specified interface structure */ /* show specified interface structure */
static int ospf6_interface_show(struct vty *vty, struct interface *ifp) static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
json_object *json_obj, bool use_json)
{ {
struct ospf6_interface *oi; struct ospf6_interface *oi;
struct connected *c; struct connected *c;
@ -915,116 +917,299 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
struct timeval res, now; struct timeval res, now;
char duration[32]; char duration[32];
struct ospf6_lsa *lsa, *lsanext; struct ospf6_lsa *lsa, *lsanext;
json_object *json_arr;
json_object *json_addr;
default_iftype = ospf6_default_iftype(ifp); default_iftype = ospf6_default_iftype(ifp);
vty_out(vty, "%s is %s, type %s\n", ifp->name, if (use_json) {
(if_is_operative(ifp) ? "up" : "down"), json_object_string_add(json_obj, "status",
ospf6_iftype_str(default_iftype)); (if_is_operative(ifp) ? "up" : "down"));
vty_out(vty, " Interface ID: %d\n", ifp->ifindex); json_object_string_add(json_obj, "type",
ospf6_iftype_str(default_iftype));
json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
if (ifp->info == NULL) {
json_object_boolean_false_add(json_obj, "ospf6Enabled");
return 0;
}
json_object_boolean_true_add(json_obj, "ospf6Enabled");
if (ifp->info == NULL) {
vty_out(vty, " OSPF not enabled on this interface\n");
return 0;
} else
oi = (struct ospf6_interface *)ifp->info; oi = (struct ospf6_interface *)ifp->info;
if (if_is_operative(ifp) && oi->type != default_iftype) if (if_is_operative(ifp) && oi->type != default_iftype)
vty_out(vty, " Operating as type %s\n", json_object_string_add(json_obj, "operatingAsType",
ospf6_iftype_str(oi->type)); ospf6_iftype_str(oi->type));
vty_out(vty, " Internet Address:\n"); } else {
vty_out(vty, "%s is %s, type %s\n", ifp->name,
(if_is_operative(ifp) ? "up" : "down"),
ospf6_iftype_str(default_iftype));
vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { if (ifp->info == NULL) {
p = c->address; vty_out(vty, " OSPF not enabled on this interface\n");
switch (p->family) { return 0;
case AF_INET: }
vty_out(vty, " inet : %pFX\n", p); oi = (struct ospf6_interface *)ifp->info;
break;
case AF_INET6: if (if_is_operative(ifp) && oi->type != default_iftype)
vty_out(vty, " inet6: %pFX\n", p); vty_out(vty, " Operating as type %s\n",
break; ospf6_iftype_str(oi->type));
default: }
vty_out(vty, " ??? : %pFX\n", p);
break; if (use_json) {
json_arr = json_object_new_array();
for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
json_addr = json_object_new_object();
p = c->address;
prefix2str(p, strbuf, sizeof(strbuf));
switch (p->family) {
case AF_INET:
json_object_string_add(json_addr, "type",
"inet");
json_object_string_add(json_addr, "address",
strbuf);
json_object_array_add(json_arr, json_addr);
break;
case AF_INET6:
json_object_string_add(json_addr, "type",
"inet6");
json_object_string_add(json_addr, "address",
strbuf);
json_object_array_add(json_arr, json_addr);
break;
default:
json_object_string_add(json_addr, "type",
"unknown");
json_object_string_add(json_addr, "address",
strbuf);
json_object_array_add(json_arr, json_addr);
break;
}
}
json_object_object_add(json_obj, "internetAddress", json_arr);
} else {
vty_out(vty, " Internet Address:\n");
for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
p = c->address;
prefix2str(p, strbuf, sizeof(strbuf));
switch (p->family) {
case AF_INET:
vty_out(vty, " inet : %pFX\n", p);
break;
case AF_INET6:
vty_out(vty, " inet6: %pFX\n", p);
break;
default:
vty_out(vty, " ??? : %pFX\n", p);
break;
}
} }
} }
if (oi->area) { if (use_json) {
vty_out(vty, if (oi->area) {
" Instance ID %d, Interface MTU %d (autodetect: %d)\n", json_object_boolean_true_add(json_obj,
oi->instance_id, oi->ifmtu, ifp->mtu6); "attachedToArea");
vty_out(vty, " MTU mismatch detection: %s\n", json_object_int_add(json_obj, "instanceId",
oi->mtu_ignore ? "disabled" : "enabled"); oi->instance_id);
inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf)); json_object_int_add(json_obj, "interfaceMtu",
vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost); oi->ifmtu);
} else json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
vty_out(vty, " Not Attached to Area\n"); json_object_string_add(json_obj, "mtuMismatchDetection",
oi->mtu_ignore ? "disabled"
: "enabled");
inet_ntop(AF_INET, &oi->area->area_id, strbuf,
sizeof(strbuf));
json_object_string_add(json_obj, "areaId", strbuf);
json_object_int_add(json_obj, "cost", oi->cost);
} else
json_object_boolean_false_add(json_obj,
"attachedToArea");
vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n", } else {
ospf6_interface_state_str[oi->state], oi->transdelay, if (oi->area) {
oi->priority); vty_out(vty,
vty_out(vty, " Timer intervals configured:\n"); " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n", oi->instance_id, oi->ifmtu, ifp->mtu6);
oi->hello_interval, oi->dead_interval, oi->rxmt_interval); vty_out(vty, " MTU mismatch detection: %s\n",
oi->mtu_ignore ? "disabled" : "enabled");
inet_ntop(AF_INET, &oi->area->area_id, strbuf,
sizeof(strbuf));
vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
oi->cost);
} else
vty_out(vty, " Not Attached to Area\n");
}
if (use_json) {
json_object_string_add(json_obj, "ospf6InterfaceState",
ospf6_interface_state_str[oi->state]);
json_object_int_add(json_obj, "transmitDelaySec",
oi->transdelay);
json_object_int_add(json_obj, "priority", oi->priority);
json_object_int_add(json_obj, "timerIntervalsConfigHello",
oi->hello_interval);
json_object_int_add(json_obj, "timerIntervalsConfigDead",
oi->dead_interval);
json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
oi->rxmt_interval);
} else {
vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
ospf6_interface_state_str[oi->state], oi->transdelay,
oi->priority);
vty_out(vty, " Timer intervals configured:\n");
vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
oi->hello_interval, oi->dead_interval,
oi->rxmt_interval);
}
inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter)); inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter)); inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter); if (use_json) {
json_object_string_add(json_obj, "dr", drouter);
vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count); json_object_string_add(json_obj, "bdr", bdrouter);
json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
oi->lsdb->count);
} else {
vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
vty_out(vty, " Number of I/F scoped LSAs is %u\n",
oi->lsdb->count);
}
monotime(&now); monotime(&now);
timerclear(&res); if (use_json) {
if (oi->thread_send_lsupdate) timerclear(&res);
timersub(&oi->thread_send_lsupdate->u.sands, &now, &res); if (oi->thread_send_lsupdate)
timerstring(&res, duration, sizeof(duration)); timersub(&oi->thread_send_lsupdate->u.sands, &now,
vty_out(vty, &res);
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", timerstring(&res, duration, sizeof(duration));
oi->lsupdate_list->count, duration, json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
(oi->thread_send_lsupdate ? "on" : "off")); oi->lsupdate_list->count);
for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
vty_out(vty, " %s\n", lsa->name); duration);
json_object_string_add(
json_obj, "lsUpdateSendThread",
(oi->thread_send_lsupdate ? "on" : "off"));
timerclear(&res); json_arr = json_object_new_array();
if (oi->thread_send_lsack) for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
timersub(&oi->thread_send_lsack->u.sands, &now, &res); json_object_array_add(
timerstring(&res, duration, sizeof(duration)); json_arr, json_object_new_string(lsa->name));
vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", json_object_object_add(json_obj, "pendingLsaLsUpdate",
oi->lsack_list->count, duration, json_arr);
(oi->thread_send_lsack ? "on" : "off"));
for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) timerclear(&res);
vty_out(vty, " %s\n", lsa->name); if (oi->thread_send_lsack)
ospf6_bfd_show_info(vty, oi->bfd_info, 1, NULL, false); timersub(&oi->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_obj, "pendingLsaLsAckCount",
oi->lsack_list->count);
json_object_string_add(json_obj, "pendingLsaLsAckTime",
duration);
json_object_string_add(json_obj, "lsAckSendThread",
(oi->thread_send_lsack ? "on" : "off"));
json_arr = json_object_new_array();
for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
json_object_array_add(
json_arr, json_object_new_string(lsa->name));
json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
} else {
timerclear(&res);
if (oi->thread_send_lsupdate)
timersub(&oi->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
oi->lsupdate_list->count, duration,
(oi->thread_send_lsupdate ? "on" : "off"));
for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
if (oi->thread_send_lsack)
timersub(&oi->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSAck in Time %s [thread %s]\n",
oi->lsack_list->count, duration,
(oi->thread_send_lsack ? "on" : "off"));
for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
}
ospf6_bfd_show_info(vty, oi->bfd_info, 1, json_obj, use_json);
return 0; return 0;
} }
/* show interface */ /* show interface */
DEFUN (show_ipv6_ospf6_interface, DEFUN(show_ipv6_ospf6_interface,
show_ipv6_ospf6_interface_ifname_cmd, show_ipv6_ospf6_interface_ifname_cmd,
"show ipv6 ospf6 interface [IFNAME]", "show ipv6 ospf6 interface [IFNAME] [json]",
SHOW_STR SHOW_STR
IP6_STR IP6_STR
OSPF6_STR OSPF6_STR
INTERFACE_STR INTERFACE_STR
IFNAME_STR) IFNAME_STR
JSON_STR)
{ {
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
int idx_ifname = 4; int idx_ifname = 4;
struct interface *ifp; struct interface *ifp;
json_object *json;
json_object *json_int;
bool uj = use_json(argc, argv);
if (argc == 5) { if (uj) {
ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); json = json_object_new_object();
if (ifp == NULL) { if (argc == 6) {
vty_out(vty, "No such Interface: %s\n", ifp = if_lookup_by_name(argv[idx_ifname]->arg,
argv[idx_ifname]->arg); VRF_DEFAULT);
return CMD_WARNING; json_int = json_object_new_object();
if (ifp == NULL) {
json_object_string_add(json, "noSuchInterface",
argv[idx_ifname]->arg);
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
json_object_free(json_int);
return CMD_WARNING;
}
ospf6_interface_show(vty, ifp, json_int, uj);
json_object_object_add(json, ifp->name, json_int);
} else {
FOR_ALL_INTERFACES (vrf, ifp) {
json_int = json_object_new_object();
ospf6_interface_show(vty, ifp, json_int, uj);
json_object_object_add(json, ifp->name,
json_int);
}
} }
ospf6_interface_show(vty, ifp); vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json);
} else { } else {
FOR_ALL_INTERFACES (vrf, ifp) if (argc == 5) {
ospf6_interface_show(vty, ifp); ifp = if_lookup_by_name(argv[idx_ifname]->arg,
VRF_DEFAULT);
if (ifp == NULL) {
vty_out(vty, "No such Interface: %s\n",
argv[idx_ifname]->arg);
return CMD_WARNING;
}
ospf6_interface_show(vty, ifp, NULL, uj);
} else {
FOR_ALL_INTERFACES (vrf, ifp)
ospf6_interface_show(vty, ifp, NULL, uj);
}
} }
return CMD_SUCCESS; return CMD_SUCCESS;