]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: Json support added for command "show ipv6 ospf6 interface [json]" 7453/head
authorgithub login name <ranjany@vmware.com>
Fri, 9 Oct 2020 06:27:37 +0000 (23:27 -0700)
committerYash Ranjan <ranjany@vmware.com>
Tue, 17 Nov 2020 05:18:39 +0000 (21:18 -0800)
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>
doc/user/ospf6d.rst
ospf6d/ospf6_bfd.c
ospf6d/ospf6_bfd.h
ospf6d/ospf6_interface.c

index dd53d8f8b4b3604e3d1f1504494c15bd158b404f..91c212c410b7e13336e605f421826c598c6b33af 100644 (file)
@@ -174,10 +174,11 @@ Showing OSPF6 information
 
    This command shows LSA database summary. You can specify the type of LSA.
 
-.. index:: show ipv6 ospf6 interface
-.. clicmd:: show ipv6 ospf6 interface
+.. index:: show ipv6 ospf6 interface [json]
+.. 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]
 .. clicmd:: show ipv6 ospf6 neighbor [json]
index 523ed7f1811e0c7bc80035541fd7bab89ec2811b..a701583621fe2d1378523185d0d33f06b3ffafef 100644 (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)
 {
        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
                bfd_show_info(vty, bfd_info, 0, 1, use_json, json_obj);
 }
index b4e798e911ca0393d45455ca5bb625b71b85b34f..ddf624efceb42e41d6898e50b7c7e16bcf9c3db5 100644 (file)
@@ -22,6 +22,7 @@
 #include "lib/json.h"
 #ifndef OSPF6_BFD_H
 #define OSPF6_BFD_H
+#include "lib/json.h"
 
 extern void ospf6_bfd_init(void);
 
index 2d1b5e7b5a5682f86e66d2f3d973eb80ff4bfd7b..1351602619951291e823d5e292c834ba9e0e62a2 100644 (file)
@@ -43,6 +43,7 @@
 #include "ospf6d.h"
 #include "ospf6_bfd.h"
 #include "ospf6_zebra.h"
+#include "lib/json.h"
 
 DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
 DEFINE_QOBJ_TYPE(ospf6_interface)
@@ -904,7 +905,8 @@ static const char *ospf6_iftype_str(uint8_t iftype)
 }
 
 /* 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 connected *c;
@@ -915,116 +917,299 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
        struct timeval res, now;
        char duration[32];
        struct ospf6_lsa *lsa, *lsanext;
+       json_object *json_arr;
+       json_object *json_addr;
 
        default_iftype = ospf6_default_iftype(ifp);
 
-       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);
+       if (use_json) {
+               json_object_string_add(json_obj, "status",
+                                      (if_is_operative(ifp) ? "up" : "down"));
+               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;
 
-       if (if_is_operative(ifp) && oi->type != default_iftype)
-               vty_out(vty, "  Operating as type %s\n",
-                       ospf6_iftype_str(oi->type));
-
-       vty_out(vty, "  Internet Address:\n");
-
-       for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
-               p = c->address;
-               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 (if_is_operative(ifp) && oi->type != default_iftype)
+                       json_object_string_add(json_obj, "operatingAsType",
+                                              ospf6_iftype_str(oi->type));
+
+       } 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);
+
+               if (ifp->info == NULL) {
+                       vty_out(vty, "   OSPF not enabled on this interface\n");
+                       return 0;
                }
+               oi = (struct ospf6_interface *)ifp->info;
+
+               if (if_is_operative(ifp) && oi->type != default_iftype)
+                       vty_out(vty, "  Operating as type %s\n",
+                               ospf6_iftype_str(oi->type));
        }
 
-       if (oi->area) {
-               vty_out(vty,
-                       "  Instance ID %d, Interface MTU %d (autodetect: %d)\n",
-                       oi->instance_id, oi->ifmtu, ifp->mtu6);
-               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_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 (use_json) {
+               if (oi->area) {
+                       json_object_boolean_true_add(json_obj,
+                                                    "attachedToArea");
+                       json_object_int_add(json_obj, "instanceId",
+                                           oi->instance_id);
+                       json_object_int_add(json_obj, "interfaceMtu",
+                                           oi->ifmtu);
+                       json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
+                       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");
+
+       } else {
+               if (oi->area) {
+                       vty_out(vty,
+                               "  Instance ID %d, Interface MTU %d (autodetect: %d)\n",
+                               oi->instance_id, oi->ifmtu, ifp->mtu6);
+                       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");
+       }
 
-       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);
+       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->bdrouter, bdrouter, sizeof(bdrouter));
-       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);
+       if (use_json) {
+               json_object_string_add(json_obj, "dr", drouter);
+               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);
 
-       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, NULL, false);
+       if (use_json) {
+               timerclear(&res);
+               if (oi->thread_send_lsupdate)
+                       timersub(&oi->thread_send_lsupdate->u.sands, &now,
+                                &res);
+               timerstring(&res, duration, sizeof(duration));
+               json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
+                                   oi->lsupdate_list->count);
+               json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
+                                      duration);
+               json_object_string_add(
+                       json_obj, "lsUpdateSendThread",
+                       (oi->thread_send_lsupdate ? "on" : "off"));
+
+               json_arr = json_object_new_array();
+               for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
+                       json_object_array_add(
+                               json_arr, json_object_new_string(lsa->name));
+               json_object_object_add(json_obj, "pendingLsaLsUpdate",
+                                      json_arr);
+
+               timerclear(&res);
+               if (oi->thread_send_lsack)
+                       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;
 }
 
 /* show interface */
-DEFUN (show_ipv6_ospf6_interface,
-       show_ipv6_ospf6_interface_ifname_cmd,
-       "show ipv6 ospf6 interface [IFNAME]",
-       SHOW_STR
-       IP6_STR
-       OSPF6_STR
-       INTERFACE_STR
-       IFNAME_STR)
+DEFUN(show_ipv6_ospf6_interface,
+      show_ipv6_ospf6_interface_ifname_cmd,
+      "show ipv6 ospf6 interface [IFNAME] [json]",
+      SHOW_STR
+      IP6_STR
+      OSPF6_STR
+      INTERFACE_STR
+      IFNAME_STR
+      JSON_STR)
 {
        struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
        int idx_ifname = 4;
        struct interface *ifp;
-
-       if (argc == 5) {
-               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;
+       json_object *json;
+       json_object *json_int;
+       bool uj = use_json(argc, argv);
+
+       if (uj) {
+               json = json_object_new_object();
+               if (argc == 6) {
+                       ifp = if_lookup_by_name(argv[idx_ifname]->arg,
+                                               VRF_DEFAULT);
+                       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 {
-               FOR_ALL_INTERFACES (vrf, ifp)
-                       ospf6_interface_show(vty, ifp);
+               if (argc == 5) {
+                       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;