]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospf6d: Json support added for command "show ipv6 ospf6 [json]"
authorgithub login name <ranjany@vmware.com>
Tue, 13 Oct 2020 12:44:52 +0000 (05:44 -0700)
committerYash Ranjan <ranjany@vmware.com>
Tue, 17 Nov 2020 03:37:26 +0000 (19:37 -0800)
Modify code to add JSON format output in show command
"show ipv6 ospf6" with proper formating.

Signed-off-by: Yash Ranjan <ranjany@vmware.com>
doc/user/ospf6d.rst
ospf6d/ospf6_area.c
ospf6d/ospf6_area.h
ospf6d/ospf6_top.c

index dd53d8f8b4b3604e3d1f1504494c15bd158b404f..598c0dbd390e80672160d4c231ccf955d1e5ac78 100644 (file)
@@ -163,11 +163,12 @@ Redistribute routes to OSPF6
 Showing OSPF6 information
 =========================
 
-.. index:: show ipv6 ospf6 [INSTANCE_ID]
-.. clicmd:: show ipv6 ospf6 [INSTANCE_ID]
+.. index:: show ipv6 ospf6 [INSTANCE_ID] [json]
+.. clicmd:: show ipv6 ospf6 [INSTANCE_ID] [json]
 
    INSTANCE_ID is an optional OSPF instance ID. To see router ID and OSPF
-   instance ID, simply type "show ipv6 ospf6 <cr>".
+   instance ID, simply type "show ipv6 ospf6 <cr>". JSON output can be
+   obtained by appending 'json' to the end of command.
 
 .. index:: show ipv6 ospf6 database
 .. clicmd:: show ipv6 ospf6 database
index e98764cd26d61130663e099d8d14ebb3b967a5d9..2ef61ae0cd514dc942d6dc542f9e9556a3f3ba70 100644 (file)
@@ -359,40 +359,94 @@ void ospf6_area_disable(struct ospf6_area *oa)
 }
 
 
-void ospf6_area_show(struct vty *vty, struct ospf6_area *oa)
+void ospf6_area_show(struct vty *vty, struct ospf6_area *oa,
+                    json_object *json_areas, bool use_json)
 {
        struct listnode *i;
        struct ospf6_interface *oi;
        unsigned long result;
+       json_object *json_area;
+       json_object *array_interfaces;
 
-       if (!IS_AREA_STUB(oa))
-               vty_out(vty, " Area %s\n", oa->name);
-       else {
-               if (oa->no_summary) {
-                       vty_out(vty, " Area %s[Stub, No Summary]\n", oa->name);
-               } else {
-                       vty_out(vty, " Area %s[Stub]\n", oa->name);
+       if (use_json) {
+               json_area = json_object_new_object();
+               json_object_boolean_add(json_area, "areaIsStub",
+                                       IS_AREA_STUB(oa));
+               if (IS_AREA_STUB(oa)) {
+                       json_object_boolean_add(json_area, "areaNoSummary",
+                                               oa->no_summary);
                }
-       }
-       vty_out(vty, "     Number of Area scoped LSAs is %u\n",
-               oa->lsdb->count);
-
-       vty_out(vty, "     Interface attached to this area:");
-       for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi))
-               vty_out(vty, " %s", oi->interface->name);
-       vty_out(vty, "\n");
-
-       if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) {
-               result = monotime_since(&oa->ts_spf, NULL);
-               if (result / TIMER_SECOND_MICRO > 0) {
-                       vty_out(vty, "SPF last executed %ld.%lds ago\n",
-                               result / TIMER_SECOND_MICRO,
-                               result % TIMER_SECOND_MICRO);
-               } else {
-                       vty_out(vty, "SPF last executed %ldus ago\n", result);
+
+               json_object_int_add(json_area, "numberOfAreaScopedLsa",
+                                   oa->lsdb->count);
+
+               /* Interfaces Attached */
+               array_interfaces = json_object_new_array();
+               for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi))
+                       json_object_array_add(
+                               array_interfaces,
+                               json_object_new_string(oi->interface->name));
+
+               json_object_object_add(json_area, "interfacesAttachedToArea",
+                                      array_interfaces);
+
+               if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) {
+                       json_object_boolean_true_add(json_area, "spfHasRun");
+                       result = monotime_since(&oa->ts_spf, NULL);
+                       if (result / TIMER_SECOND_MICRO > 0) {
+                               json_object_int_add(
+                                       json_area, "spfLastExecutedSecs",
+                                       result / TIMER_SECOND_MICRO);
+
+                               json_object_int_add(
+                                       json_area, "spfLastExecutedMicroSecs",
+                                       result % TIMER_SECOND_MICRO);
+                       } else {
+                               json_object_int_add(json_area,
+                                                   "spfLastExecutedSecs", 0);
+                               json_object_int_add(json_area,
+                                                   "spfLastExecutedMicroSecs",
+                                                   result);
+                       }
+               } else
+                       json_object_boolean_false_add(json_area, "spfHasRun");
+
+
+               json_object_object_add(json_areas, oa->name, json_area);
+
+       } else {
+
+               if (!IS_AREA_STUB(oa))
+                       vty_out(vty, " Area %s\n", oa->name);
+               else {
+                       if (oa->no_summary) {
+                               vty_out(vty, " Area %s[Stub, No Summary]\n",
+                                       oa->name);
+                       } else {
+                               vty_out(vty, " Area %s[Stub]\n", oa->name);
+                       }
                }
-       } else
-               vty_out(vty, "SPF has not been run\n");
+               vty_out(vty, "     Number of Area scoped LSAs is %u\n",
+                       oa->lsdb->count);
+
+               vty_out(vty, "     Interface attached to this area:");
+               for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi))
+                       vty_out(vty, " %s", oi->interface->name);
+               vty_out(vty, "\n");
+
+               if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) {
+                       result = monotime_since(&oa->ts_spf, NULL);
+                       if (result / TIMER_SECOND_MICRO > 0) {
+                               vty_out(vty, "SPF last executed %ld.%lds ago\n",
+                                       result / TIMER_SECOND_MICRO,
+                                       result % TIMER_SECOND_MICRO);
+                       } else {
+                               vty_out(vty, "SPF last executed %ldus ago\n",
+                                       result);
+                       }
+               } else
+                       vty_out(vty, "SPF has not been run\n");
+       }
 }
 
 DEFUN (area_range,
index 2097ef6e43c61ec4d59da7068457664b01457077..8a58b2a50ed571da8dc46e6f8dc7e4e75b4d2107 100644 (file)
@@ -22,6 +22,7 @@
 #define OSPF_AREA_H
 
 #include "ospf6_top.h"
+#include "lib/json.h"
 
 struct ospf6_area {
        /* Reference to Top data structure */
@@ -143,7 +144,8 @@ extern struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id);
 extern void ospf6_area_enable(struct ospf6_area *);
 extern void ospf6_area_disable(struct ospf6_area *);
 
-extern void ospf6_area_show(struct vty *, struct ospf6_area *);
+extern void ospf6_area_show(struct vty *, struct ospf6_area *,
+                           json_object *json_areas, bool use_json);
 
 extern void ospf6_area_plist_update(struct prefix_list *plist, int add);
 extern void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6);
index 95c72290d0ce24a3f89bb03ff69002c0eec55603..cbfa8ba3d524147b76fe0155f70dcde091cc54b1 100644 (file)
@@ -29,6 +29,7 @@
 #include "thread.h"
 #include "command.h"
 #include "defaults.h"
+#include "lib/json.h"
 #include "lib_errors.h"
 
 #include "ospf6_proto.h"
@@ -954,90 +955,207 @@ DEFUN (no_ospf6_stub_router_shutdown,
 }
 #endif
 
-static void ospf6_show(struct vty *vty, struct ospf6 *o)
+
+static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
+                      bool use_json)
 {
        struct listnode *n;
        struct ospf6_area *oa;
        char router_id[16], duration[32];
        struct timeval now, running, result;
        char buf[32], rbuf[32];
+       json_object *json_areas = NULL;
+       const char *adjacency;
+
+       if (use_json) {
+               json_areas = json_object_new_object();
+
+               /* process id, router id */
+               inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
+               json_object_string_add(json, "routerId", router_id);
+
+               /* running time */
+               monotime(&now);
+               timersub(&now, &o->starttime, &running);
+               timerstring(&running, duration, sizeof(duration));
+               json_object_string_add(json, "running", duration);
+
+               /* Redistribute configuration */
+               /* XXX */
+               json_object_int_add(json, "lsaMinimumArrivalMsecs",
+                                   o->lsa_minarrival);
+
+               /* Show SPF parameters */
+               json_object_int_add(json, "spfScheduleDelayMsecs",
+                                   o->spf_delay);
+               json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime);
+               json_object_int_add(json, "holdTimeMaxMsecs",
+                                   o->spf_max_holdtime);
+               json_object_int_add(json, "holdTimeMultiplier",
+                                   o->spf_hold_multiplier);
+
+
+               if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
+                       timersub(&now, &o->ts_spf, &result);
+                       timerstring(&result, buf, sizeof(buf));
+                       ospf6_spf_reason_string(o->last_spf_reason, rbuf,
+                                               sizeof(rbuf));
+                       json_object_boolean_true_add(json, "spfHasRun");
+                       json_object_string_add(json, "spfLastExecutedMsecs",
+                                              buf);
+                       json_object_string_add(json, "spfLastExecutedReason",
+                                              rbuf);
+
+                       json_object_int_add(
+                               json, "spfLastDurationSecs",
+                               (long long)o->ts_spf_duration.tv_sec);
+
+                       json_object_int_add(
+                               json, "spfLastDurationMsecs",
+                               (long long)o->ts_spf_duration.tv_usec);
+               } else
+                       json_object_boolean_false_add(json, "spfHasRun");
+
+
+               threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
+               if (o->t_spf_calc) {
+                       long time_store;
+
+                       json_object_boolean_true_add(json, "spfTimerActive");
+                       time_store =
+                               monotime_until(&o->t_spf_calc->u.sands, NULL)
+                               / 1000LL;
+                       json_object_int_add(json, "spfTimerDueInMsecs",
+                                           time_store);
+               } else
+                       json_object_boolean_false_add(json, "spfTimerActive");
+
+               json_object_boolean_add(json, "routerIsStubRouter",
+                                       CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
+
+               /* LSAs */
+               json_object_int_add(json, "numberOfAsScopedLsa",
+                                   o->lsdb->count);
+               /* Areas */
+               json_object_int_add(json, "numberOfAreaInRouter",
+                                   listcount(o->area_list));
+
+               if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
+                       if (CHECK_FLAG(o->config_flags,
+                                      OSPF6_LOG_ADJACENCY_DETAIL))
+                               adjacency = "LoggedAll";
+                       else
+                               adjacency = "Logged";
+               } else
+                       adjacency = "NotLogged";
+               json_object_string_add(json, "adjacencyChanges", adjacency);
+
+               for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
+                       ospf6_area_show(vty, oa, json_areas, use_json);
+
+               json_object_object_add(json, "areas", json_areas);
+
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+
+       } else {
+               /* process id, router id */
+               inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
+               vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
+                       router_id);
+
+               /* running time */
+               monotime(&now);
+               timersub(&now, &o->starttime, &running);
+               timerstring(&running, duration, sizeof(duration));
+               vty_out(vty, " Running %s\n", duration);
+
+               /* Redistribute configuration */
+               /* XXX */
+               vty_out(vty, " LSA minimum arrival %d msecs\n",
+                       o->lsa_minarrival);
+
+
+               /* Show SPF parameters */
+               vty_out(vty,
+                       " Initial SPF scheduling delay %d millisec(s)\n"
+                       " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
+                       " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
+                       " Hold time multiplier is currently %d\n",
+                       o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
+                       o->spf_hold_multiplier);
+
+
+               vty_out(vty, " SPF algorithm ");
+               if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
+                       timersub(&now, &o->ts_spf, &result);
+                       timerstring(&result, buf, sizeof(buf));
+                       ospf6_spf_reason_string(o->last_spf_reason, rbuf,
+                                               sizeof(rbuf));
+                       vty_out(vty, "last executed %s ago, reason %s\n", buf,
+                               rbuf);
+                       vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
+                               (long long)o->ts_spf_duration.tv_sec,
+                               (long long)o->ts_spf_duration.tv_usec);
+               } else
+                       vty_out(vty, "has not been run\n");
+
+               threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
+               vty_out(vty, " SPF timer %s%s\n",
+                       (o->t_spf_calc ? "due in " : "is "), buf);
+
+               if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
+                       vty_out(vty, " Router Is Stub Router\n");
+
+               /* LSAs */
+               vty_out(vty, " Number of AS scoped LSAs is %u\n",
+                       o->lsdb->count);
+
+               /* Areas */
+               vty_out(vty, " Number of areas in this router is %u\n",
+                       listcount(o->area_list));
+
+               if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
+                       if (CHECK_FLAG(o->config_flags,
+                                      OSPF6_LOG_ADJACENCY_DETAIL))
+                               vty_out(vty,
+                                       " All adjacency changes are logged\n");
+                       else
+                               vty_out(vty, " Adjacency changes are logged\n");
+               }
 
-       /* process id, router id */
-       inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
-       vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
-               router_id);
-
-       /* running time */
-       monotime(&now);
-       timersub(&now, &o->starttime, &running);
-       timerstring(&running, duration, sizeof(duration));
-       vty_out(vty, " Running %s\n", duration);
-
-       /* Redistribute configuration */
-       /* XXX */
-
-       vty_out(vty, " LSA minimum arrival %d msecs\n", o->lsa_minarrival);
-
-       /* Show SPF parameters */
-       vty_out(vty,
-               " Initial SPF scheduling delay %d millisec(s)\n"
-               " Minimum hold time between consecutive SPFs %d millsecond(s)\n"
-               " Maximum hold time between consecutive SPFs %d millsecond(s)\n"
-               " Hold time multiplier is currently %d\n",
-               o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
-               o->spf_hold_multiplier);
-
-       vty_out(vty, " SPF algorithm ");
-       if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
-               timersub(&now, &o->ts_spf, &result);
-               timerstring(&result, buf, sizeof(buf));
-               ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf));
-               vty_out(vty, "last executed %s ago, reason %s\n", buf, rbuf);
-               vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
-                       (long long)o->ts_spf_duration.tv_sec,
-                       (long long)o->ts_spf_duration.tv_usec);
-       } else
-               vty_out(vty, "has not been run\n");
-       threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
-       vty_out(vty, " SPF timer %s%s\n", (o->t_spf_calc ? "due in " : "is "),
-               buf);
-
-       if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
-               vty_out(vty, " Router Is Stub Router\n");
-
-       /* LSAs */
-       vty_out(vty, " Number of AS scoped LSAs is %u\n", o->lsdb->count);
-
-       /* Areas */
-       vty_out(vty, " Number of areas in this router is %u\n",
-               listcount(o->area_list));
-
-       if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
-               if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
-                       vty_out(vty, " All adjacency changes are logged\n");
-               else
-                       vty_out(vty, " Adjacency changes are logged\n");
-       }
 
-       vty_out(vty, "\n");
+               vty_out(vty, "\n");
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
-               ospf6_area_show(vty, oa);
+               for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
+                       ospf6_area_show(vty, oa, json_areas, use_json);
+       }
 }
 
 /* show top level structures */
-DEFUN (show_ipv6_ospf6,
-       show_ipv6_ospf6_cmd,
-       "show ipv6 ospf6",
-       SHOW_STR
-       IP6_STR
-       OSPF6_STR)
+DEFUN(show_ipv6_ospf6,
+      show_ipv6_ospf6_cmd,
+      "show ipv6 ospf6 [json]",
+      SHOW_STR
+      IP6_STR
+      OSPF6_STR
+      JSON_STR)
 {
        struct ospf6 *ospf6;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
-       ospf6_show(vty, ospf6);
+
+       if (uj)
+               json = json_object_new_object();
+
+       ospf6_show(vty, ospf6, json, uj);
+
+       if (uj)
+               json_object_free(json);
        return CMD_SUCCESS;
 }