]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: Json support added for command "show ipv6 ospf6 route [json]"
authorYash Ranjan <ranjany@vmware.com>
Wed, 28 Oct 2020 10:51:39 +0000 (03:51 -0700)
committerYash Ranjan <ranjany@vmware.com>
Wed, 27 Jan 2021 04:06:02 +0000 (20:06 -0800)
Modify code to add JSON format output in show command
"show ipv6 ospf6 route [<intra-area|inter-area|external-1|
external-2|X:X::X:X|X:X::X:X/M|detail|summary>]"
with proper formating

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

index b00bdb3ab8f4e49a6287ca774fa02011310ecc13..9d1c2e0b9d07d8a97061566d37d4d1b82a59e85a 100644 (file)
@@ -240,6 +240,21 @@ Showing OSPF6 information
    Shows the routes which are redistributed by the router. JSON output can
    be obtained by appending 'json' at the end.
 
+.. index:: show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]
+.. clicmd:: show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]
+
+   This command displays the ospfv3 routing table as determined by the most
+   recent SPF calculations. Options are provided to view the different types
+   of routes. Other than the standard view there are two other options, detail
+   and summary. JSON output can be obtained by appending 'json' to the end of
+   command.
+
+.. index:: show ipv6 ospf6 route X:X::X:X/M match [detail] [json]
+.. clicmd:: show ipv6 ospf6 route X:X::X:X/M match [detail] [json]
+
+   The additional match option will match the given address to the destination
+   of the routes, and return the result accordingly.
+
 OSPF6 Configuration Examples
 ============================
 
index 948880a4b59f6f9bb50ea23a71bcabad1e76e0f1..fd5878921257109a6d1acacabb6b6ab324d1a2a2 100644 (file)
@@ -1447,8 +1447,8 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
                return CMD_WARNING;
        }
 
-       ospf6_route_table_show(vty, idx_prefix, argc, argv,
-                              oi->route_connected);
+       ospf6_route_table_show(vty, idx_prefix, argc, argv, oi->route_connected,
+                              false);
 
        return CMD_SUCCESS;
 }
@@ -1482,7 +1482,7 @@ DEFUN (show_ipv6_ospf6_interface_prefix,
                        continue;
 
                ospf6_route_table_show(vty, idx_prefix, argc, argv,
-                                      oi->route_connected);
+                                      oi->route_connected, false);
        }
 
        return CMD_SUCCESS;
index 60c208437bc3ba6e3f67748d0a54676477870c8f..b77f968179d811702df64b1b606917f6f23f60b3 100644 (file)
@@ -163,6 +163,10 @@ const char *const ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX] = {
        "??", "IA", "IE", "E1", "E2",
 };
 
+const char *ospf6_path_type_json[OSPF6_PATH_TYPE_MAX] = {
+       "UnknownRoute", "IntraArea", "InterArea", "External1", "External2",
+};
+
 
 struct ospf6_nexthop *ospf6_nexthop_create(void)
 {
@@ -1030,7 +1034,8 @@ void ospf6_route_table_delete(struct ospf6_route_table *table)
 
 
 /* VTY commands */
-void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
+void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
+                     json_object *json_array_routes, bool use_json)
 {
        int i;
        char destination[PREFIX2STR_BUFFER], nexthop[64];
@@ -1038,6 +1043,9 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
        struct timeval now, res;
        struct listnode *node;
        struct ospf6_nexthop *nh;
+       json_object *json_route = NULL;
+       json_object *json_array_next_hops = NULL;
+       json_object *json_next_hop;
 
        if (om6->ospf6 == NULL) {
                vty_out(vty, "OSPFv3 is not running\n");
@@ -1058,34 +1066,74 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
        else
                prefix2str(&route->prefix, destination, sizeof(destination));
 
-       i = 0;
+       if (use_json) {
+               json_route = json_object_new_object();
+               json_object_string_add(json_route, "destination", destination);
+               json_object_boolean_add(json_route, "isBestRoute",
+                                       ospf6_route_is_best(route));
+               json_object_string_add(json_route, "destinationType",
+                                      OSPF6_DEST_TYPE_SUBSTR(route->type));
+               json_object_string_add(
+                       json_route, "pathType",
+                       OSPF6_PATH_TYPE_SUBSTR(route->path.type));
+               json_object_string_add(json_route, "duration", duration);
+       }
+
+       /* Nexthops */
+       if (use_json)
+               json_array_next_hops = json_object_new_array();
+       else
+               i = 0;
        for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
                struct interface *ifp;
                /* nexthop */
                inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop));
                ifp = if_lookup_by_index_all_vrf(nh->ifindex);
-               if (!i) {
-                       vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n",
-                               (ospf6_route_is_best(route) ? '*' : ' '),
-                               OSPF6_DEST_TYPE_SUBSTR(route->type),
-                               OSPF6_PATH_TYPE_SUBSTR(route->path.type),
-                               destination, nexthop, IFNAMSIZ, ifp->name,
-                               duration);
-                       i++;
-               } else
-                       vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", ' ',
-                               "", "", "", nexthop, IFNAMSIZ, ifp->name, "");
+               if (use_json) {
+                       json_next_hop = json_object_new_object();
+                       json_object_string_add(json_next_hop, "nextHop",
+                                              nexthop);
+                       json_object_string_add(json_next_hop, "interfaceName",
+                                              ifp->name);
+                       json_object_array_add(json_array_next_hops,
+                                             json_next_hop);
+               } else {
+                       if (!i) {
+                               vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n",
+                                       (ospf6_route_is_best(route) ? '*'
+                                                                   : ' '),
+                                       OSPF6_DEST_TYPE_SUBSTR(route->type),
+                                       OSPF6_PATH_TYPE_SUBSTR(
+                                               route->path.type),
+                                       destination, nexthop, IFNAMSIZ,
+                                       ifp->name, duration);
+                               i++;
+                       } else
+                               vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n",
+                                       ' ', "", "", "", nexthop, IFNAMSIZ,
+                                       ifp->name, "");
+               }
+       }
+       if (use_json) {
+               json_object_object_add(json_route, "nextHops",
+                                      json_array_next_hops);
+               json_object_array_add(json_array_routes, json_route);
        }
 }
 
-void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
+void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
+                            json_object *json_array_routes, bool use_json)
 {
-       char destination[PREFIX2STR_BUFFER];
+       char destination[PREFIX2STR_BUFFER], nexthop[64];
        char area_id[16], id[16], adv_router[16], capa[16], options[16];
        struct timeval now, res;
        char duration[64];
        struct listnode *node;
        struct ospf6_nexthop *nh;
+       char flag[6];
+       json_object *json_route = NULL;
+       json_object *json_array_next_hops = NULL;
+       json_object *json_next_hop;
 
        if (om6->ospf6 == NULL) {
                vty_out(vty, "OSPFv3 is not running\n");
@@ -1103,84 +1151,177 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
                          destination, sizeof(destination));
        else
                prefix2str(&route->prefix, destination, sizeof(destination));
-       vty_out(vty, "Destination: %s\n", destination);
 
-       /* destination type */
-       vty_out(vty, "Destination type: %s\n",
-               OSPF6_DEST_TYPE_NAME(route->type));
+       if (use_json) {
+               json_route = json_object_new_object();
+               json_object_string_add(json_route, "destination", destination);
+               json_object_string_add(json_route, "destinationType",
+                                      OSPF6_DEST_TYPE_NAME(route->type));
+       } else {
+               vty_out(vty, "Destination: %s\n", destination);
+               vty_out(vty, "Destination type: %s\n",
+                       OSPF6_DEST_TYPE_NAME(route->type));
+       }
 
        /* Time */
        timersub(&now, &route->installed, &res);
        timerstring(&res, duration, sizeof(duration));
-       vty_out(vty, "Installed Time: %s ago\n", duration);
+       if (use_json)
+               json_object_string_add(json_route, "installedTimeSince",
+                                      duration);
+       else
+               vty_out(vty, "Installed Time: %s ago\n", duration);
 
        timersub(&now, &route->changed, &res);
        timerstring(&res, duration, sizeof(duration));
-       vty_out(vty, "  Changed Time: %s ago\n", duration);
+       if (use_json)
+               json_object_string_add(json_route, "changedTimeSince",
+                                      duration);
+       else
+               vty_out(vty, "Changed Time: %s ago\n", duration);
 
        /* Debugging info */
-       vty_out(vty, "Lock: %d Flags: %s%s%s%s\n", route->lock,
-               (CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
-               (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
-               (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
-               (CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
-       vty_out(vty, "Memory: prev: %p this: %p next: %p\n",
-               (void *)route->prev, (void *)route, (void *)route->next);
+       if (use_json) {
+               json_object_int_add(json_route, "numberOfLock", route->lock);
+               snprintf(
+                       flag, sizeof(flag), "%s%s%s%s",
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) ? "R"
+                                                                    : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE) ? "C"
+                                                                    : "-"));
+               json_object_string_add(json_route, "flags", flag);
+       } else {
+               vty_out(vty, "Lock: %d Flags: %s%s%s%s\n", route->lock,
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) ? "R"
+                                                                    : "-"),
+                       (CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE) ? "C"
+                                                                    : "-"));
+               vty_out(vty, "Memory: prev: %p this: %p next: %p\n",
+                       (void *)route->prev, (void *)route,
+                       (void *)route->next);
+       }
 
        /* Path section */
 
        /* Area-ID */
        inet_ntop(AF_INET, &route->path.area_id, area_id, sizeof(area_id));
-       vty_out(vty, "Associated Area: %s\n", area_id);
+       if (use_json)
+               json_object_string_add(json_route, "associatedArea", area_id);
+       else
+               vty_out(vty, "Associated Area: %s\n", area_id);
 
        /* Path type */
-       vty_out(vty, "Path Type: %s\n", OSPF6_PATH_TYPE_NAME(route->path.type));
+       if (use_json)
+               json_object_string_add(json_route, "pathType",
+                                      OSPF6_PATH_TYPE_NAME(route->path.type));
+       else
+               vty_out(vty, "Path Type: %s\n",
+                       OSPF6_PATH_TYPE_NAME(route->path.type));
 
        /* LS Origin */
        inet_ntop(AF_INET, &route->path.origin.id, id, sizeof(id));
        inet_ntop(AF_INET, &route->path.origin.adv_router, adv_router,
                  sizeof(adv_router));
-       vty_out(vty, "LS Origin: %s Id: %s Adv: %s\n",
-               ospf6_lstype_name(route->path.origin.type), id, adv_router);
+       if (use_json) {
+               json_object_string_add(
+                       json_route, "lsOriginRoutePathType",
+                       ospf6_lstype_name(route->path.origin.type));
+               json_object_string_add(json_route, "lsId", id);
+               json_object_string_add(json_route, "lsAdvertisingRouter",
+                                      adv_router);
+       } else {
+               vty_out(vty, "LS Origin: %s Id: %s Adv: %s\n",
+                       ospf6_lstype_name(route->path.origin.type), id,
+                       adv_router);
+       }
 
        /* Options */
        ospf6_options_printbuf(route->path.options, options, sizeof(options));
-       vty_out(vty, "Options: %s\n", options);
+       if (use_json)
+               json_object_string_add(json_route, "options", options);
+       else
+               vty_out(vty, "Options: %s\n", options);
 
        /* Router Bits */
        ospf6_capability_printbuf(route->path.router_bits, capa, sizeof(capa));
-       vty_out(vty, "Router Bits: %s\n", capa);
+       if (use_json)
+               json_object_string_add(json_route, "routerBits", capa);
+       else
+               vty_out(vty, "Router Bits: %s\n", capa);
 
        /* Prefix Options */
-       vty_out(vty, "Prefix Options: xxx\n");
+       if (use_json)
+               json_object_string_add(json_route, "prefixOptions", "xxx");
+       else
+               vty_out(vty, "Prefix Options: xxx\n");
 
        /* Metrics */
-       vty_out(vty, "Metric Type: %d\n", route->path.metric_type);
-       vty_out(vty, "Metric: %d (%d)\n", route->path.cost,
-               route->path.u.cost_e2);
+       if (use_json) {
+               json_object_int_add(json_route, "metricType",
+                                   route->path.metric_type);
+               json_object_int_add(json_route, "metricCost", route->path.cost);
+               json_object_int_add(json_route, "metricCostE2",
+                                   route->path.u.cost_e2);
+
+               json_object_int_add(json_route, "pathsCount",
+                                   route->paths->count);
+               json_object_int_add(json_route, "nextHopCount",
+                                   route->nh_list->count);
+       } else {
+               vty_out(vty, "Metric Type: %d\n", route->path.metric_type);
+               vty_out(vty, "Metric: %d (%d)\n", route->path.cost,
+                       route->path.u.cost_e2);
+
+               vty_out(vty, "Paths count: %u\n", route->paths->count);
+               vty_out(vty, "Nexthop count: %u\n", route->nh_list->count);
+       }
 
-       vty_out(vty, "Paths count: %u\n", route->paths->count);
-       vty_out(vty, "Nexthop count: %u\n", route->nh_list->count);
        /* Nexthops */
-       vty_out(vty, "Nexthop:\n");
+       if (use_json)
+               json_array_next_hops = json_object_new_array();
+       else
+               vty_out(vty, "Nexthop:\n");
+
        for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
                struct interface *ifp;
-               /* nexthop */
-
                ifp = if_lookup_by_index_all_vrf(nh->ifindex);
-               vty_out(vty, "  %pI6 %.*s\n", &nh->address, IFNAMSIZ, ifp->name);
+               /* nexthop */
+               if (use_json) {
+                       inet_ntop(AF_INET6, &nh->address, nexthop,
+                                 sizeof(nexthop));
+                       json_next_hop = json_object_new_object();
+                       json_object_string_add(json_next_hop, "nextHop",
+                                              nexthop);
+                       json_object_string_add(json_next_hop, "interfaceName",
+                                              ifp->name);
+                       json_object_array_add(json_array_next_hops,
+                                             json_next_hop);
+               } else
+                       vty_out(vty, "  %pI6 %.*s\n", &nh->address, IFNAMSIZ,
+                               ifp->name);
        }
-       vty_out(vty, "\n");
+       if (use_json) {
+               json_object_object_add(json_route, "nextHops",
+                                      json_array_next_hops);
+               json_object_array_add(json_array_routes, json_route);
+       } else
+               vty_out(vty, "\n");
 }
 
 static void ospf6_route_show_table_summary(struct vty *vty,
-                                          struct ospf6_route_table *table)
+                                          struct ospf6_route_table *table,
+                                          json_object *json, bool use_json)
 {
        struct ospf6_route *route, *prev = NULL;
        int i, pathtype[OSPF6_PATH_TYPE_MAX];
        unsigned int number = 0;
        int nh_count = 0, nhinval = 0, ecmp = 0;
        int alternative = 0, destination = 0;
+       char path_str[30];
 
        for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++)
                pathtype[i] = 0;
@@ -1203,111 +1344,164 @@ static void ospf6_route_show_table_summary(struct vty *vty,
        }
 
        assert(number == table->count);
-
-       vty_out(vty, "Number of OSPFv3 routes: %d\n", number);
-       vty_out(vty, "Number of Destination: %d\n", destination);
-       vty_out(vty, "Number of Alternative routes: %d\n", alternative);
-       vty_out(vty, "Number of Equal Cost Multi Path: %d\n", ecmp);
+       if (use_json) {
+               json_object_int_add(json, "numberOfOspfv3Routes", number);
+               json_object_int_add(json, "numberOfDestination", destination);
+               json_object_int_add(json, "numberOfAlternativeRoutes",
+                                   alternative);
+               json_object_int_add(json, "numberOfEcmp", ecmp);
+       } else {
+               vty_out(vty, "Number of OSPFv3 routes: %d\n", number);
+               vty_out(vty, "Number of Destination: %d\n", destination);
+               vty_out(vty, "Number of Alternative routes: %d\n", alternative);
+               vty_out(vty, "Number of Equal Cost Multi Path: %d\n", ecmp);
+       }
        for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++) {
-               vty_out(vty, "Number of %s routes: %d\n",
-                       OSPF6_PATH_TYPE_NAME(i), pathtype[i]);
+               if (use_json) {
+                       snprintf(path_str, sizeof(path_str), "numberOf%sRoutes",
+                                OSPF6_PATH_TYPE_JSON(i));
+                       json_object_int_add(json, path_str, pathtype[i]);
+               } else
+                       vty_out(vty, "Number of %s routes: %d\n",
+                               OSPF6_PATH_TYPE_NAME(i), pathtype[i]);
        }
 }
 
 static void ospf6_route_show_table_prefix(struct vty *vty,
                                          struct prefix *prefix,
-                                         struct ospf6_route_table *table)
+                                         struct ospf6_route_table *table,
+                                         json_object *json, bool use_json)
 {
        struct ospf6_route *route;
+       json_object *json_array_routes = NULL;
 
        route = ospf6_route_lookup(prefix, table);
        if (route == NULL)
                return;
 
+       if (use_json)
+               json_array_routes = json_object_new_array();
        ospf6_route_lock(route);
        while (route && ospf6_route_is_prefix(prefix, route)) {
                /* Specifying a prefix will always display details */
-               ospf6_route_show_detail(vty, route);
+               ospf6_route_show_detail(vty, route, json_array_routes,
+                                       use_json);
                route = ospf6_route_next(route);
        }
+
+       if (use_json)
+               json_object_object_add(json, "routes", json_array_routes);
        if (route)
                ospf6_route_unlock(route);
 }
 
 static void ospf6_route_show_table_address(struct vty *vty,
                                           struct prefix *prefix,
-                                          struct ospf6_route_table *table)
+                                          struct ospf6_route_table *table,
+                                          json_object *json, bool use_json)
 {
        struct ospf6_route *route;
+       json_object *json_array_routes = NULL;
 
        route = ospf6_route_lookup_bestmatch(prefix, table);
        if (route == NULL)
                return;
 
+       if (use_json)
+               json_array_routes = json_object_new_array();
        prefix = &route->prefix;
        ospf6_route_lock(route);
        while (route && ospf6_route_is_prefix(prefix, route)) {
                /* Specifying a prefix will always display details */
-               ospf6_route_show_detail(vty, route);
+               ospf6_route_show_detail(vty, route, json_array_routes,
+                                       use_json);
                route = ospf6_route_next(route);
        }
+       if (use_json)
+               json_object_object_add(json, "routes", json_array_routes);
        if (route)
                ospf6_route_unlock(route);
 }
 
 static void ospf6_route_show_table_match(struct vty *vty, int detail,
                                         struct prefix *prefix,
-                                        struct ospf6_route_table *table)
+                                        struct ospf6_route_table *table,
+                                        json_object *json, bool use_json)
 {
        struct ospf6_route *route;
+       json_object *json_array_routes = NULL;
+
        assert(prefix->family);
 
        route = ospf6_route_match_head(prefix, table);
+       if (use_json)
+               json_array_routes = json_object_new_array();
        while (route) {
                if (detail)
-                       ospf6_route_show_detail(vty, route);
+                       ospf6_route_show_detail(vty, route, json_array_routes,
+                                               use_json);
                else
-                       ospf6_route_show(vty, route);
+                       ospf6_route_show(vty, route, json_array_routes,
+                                        use_json);
                route = ospf6_route_match_next(prefix, route);
        }
+       if (use_json)
+               json_object_object_add(json, "routes", json_array_routes);
 }
 
 static void ospf6_route_show_table_type(struct vty *vty, int detail,
                                        uint8_t type,
-                                       struct ospf6_route_table *table)
+                                       struct ospf6_route_table *table,
+                                       json_object *json, bool use_json)
 {
        struct ospf6_route *route;
+       json_object *json_array_routes = NULL;
 
        route = ospf6_route_head(table);
+       if (use_json)
+               json_array_routes = json_object_new_array();
        while (route) {
                if (route->path.type == type) {
                        if (detail)
-                               ospf6_route_show_detail(vty, route);
+                               ospf6_route_show_detail(vty, route,
+                                                       json_array_routes,
+                                                       use_json);
                        else
-                               ospf6_route_show(vty, route);
+                               ospf6_route_show(vty, route, json_array_routes,
+                                                use_json);
                }
                route = ospf6_route_next(route);
        }
+       if (use_json)
+               json_object_object_add(json, "routes", json_array_routes);
 }
 
 static void ospf6_route_show_table(struct vty *vty, int detail,
-                                  struct ospf6_route_table *table)
+                                  struct ospf6_route_table *table,
+                                  json_object *json, bool use_json)
 {
        struct ospf6_route *route;
+       json_object *json_array_routes = NULL;
 
        route = ospf6_route_head(table);
+       if (use_json)
+               json_array_routes = json_object_new_array();
        while (route) {
                if (detail)
-                       ospf6_route_show_detail(vty, route);
+                       ospf6_route_show_detail(vty, route, json_array_routes,
+                                               use_json);
                else
-                       ospf6_route_show(vty, route);
+                       ospf6_route_show(vty, route, json_array_routes,
+                                        use_json);
                route = ospf6_route_next(route);
        }
+       if (use_json)
+               json_object_object_add(json, "routes", json_array_routes);
 }
 
 int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
                           struct cmd_token **argv,
-                          struct ospf6_route_table *table)
+                          struct ospf6_route_table *table, bool use_json)
 {
        int summary = 0;
        int match = 0;
@@ -1317,10 +1511,15 @@ int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
        int i, ret;
        struct prefix prefix;
        uint8_t type = 0;
+       int arg_end = use_json ? (argc - 1) : argc;
+       json_object *json = NULL;
 
        memset(&prefix, 0, sizeof(struct prefix));
 
-       for (i = argc_start; i < argc; i++) {
+       if (use_json)
+               json = json_object_new_object();
+
+       for (i = argc_start; i < arg_end; i++) {
                if (strmatch(argv[i]->text, "summary")) {
                        summary++;
                        continue;
@@ -1363,14 +1562,24 @@ int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
                                slash++;
                        continue;
                }
+               if (use_json)
+                       json_object_string_add(json, "malformedArgument",
+                                              argv[i]->arg);
+               else
+                       vty_out(vty, "Malformed argument: %s\n", argv[i]->arg);
 
-               vty_out(vty, "Malformed argument: %s\n", argv[i]->arg);
                return CMD_SUCCESS;
        }
 
        /* Give summary of this route table */
        if (summary) {
-               ospf6_route_show_table_summary(vty, table);
+               ospf6_route_show_table_summary(vty, table, json, use_json);
+               if (use_json) {
+                       vty_out(vty, "%s\n",
+                               json_object_to_json_string_ext(
+                                       json, JSON_C_TO_STRING_PRETTY));
+                       json_object_free(json);
+               }
                return CMD_SUCCESS;
        }
 
@@ -1378,20 +1587,36 @@ int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
        if (isprefix && !match) {
                /* If exact address, give best matching route */
                if (!slash)
-                       ospf6_route_show_table_address(vty, &prefix, table);
+                       ospf6_route_show_table_address(vty, &prefix, table,
+                                                      json, use_json);
                else
-                       ospf6_route_show_table_prefix(vty, &prefix, table);
-
+                       ospf6_route_show_table_prefix(vty, &prefix, table, json,
+                                                     use_json);
+
+               if (use_json) {
+                       vty_out(vty, "%s\n",
+                               json_object_to_json_string_ext(
+                                       json, JSON_C_TO_STRING_PRETTY));
+                       json_object_free(json);
+               }
                return CMD_SUCCESS;
        }
 
        if (match)
-               ospf6_route_show_table_match(vty, detail, &prefix, table);
+               ospf6_route_show_table_match(vty, detail, &prefix, table, json,
+                                            use_json);
        else if (type)
-               ospf6_route_show_table_type(vty, detail, type, table);
+               ospf6_route_show_table_type(vty, detail, type, table, json,
+                                           use_json);
        else
-               ospf6_route_show_table(vty, detail, table);
+               ospf6_route_show_table(vty, detail, table, json, use_json);
 
+       if (use_json) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
        return CMD_SUCCESS;
 }
 
@@ -1439,7 +1664,7 @@ static void ospf6_linkstate_show_table_exact(struct vty *vty,
        ospf6_route_lock(route);
        while (route && ospf6_route_is_prefix(prefix, route)) {
                /* Specifying a prefix will always display details */
-               ospf6_route_show_detail(vty, route);
+               ospf6_route_show_detail(vty, route, NULL, false);
                route = ospf6_route_next(route);
        }
        if (route)
@@ -1457,7 +1682,7 @@ static void ospf6_linkstate_show_table(struct vty *vty, int detail,
        route = ospf6_route_head(table);
        while (route) {
                if (detail)
-                       ospf6_route_show_detail(vty, route);
+                       ospf6_route_show_detail(vty, route, NULL, false);
                else
                        ospf6_linkstate_show(vty, route);
                route = ospf6_route_next(route);
index e2118003d5a71f729dd76d7bc8953ec94766d66e..a791a82cd4b03260e56a80c3c7c2650f14c6973b 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "command.h"
 #include "zclient.h"
+#include "lib/json.h"
 
 #define OSPF6_MULTI_PATH_LIMIT    4
 
@@ -233,6 +234,9 @@ extern const char *const ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX];
 #define OSPF6_PATH_TYPE_SUBSTR(x)                                              \
        (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_substr[(x)]    \
                                              : ospf6_path_type_substr[0])
+#define OSPF6_PATH_TYPE_JSON(x)                                                \
+       (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_json[(x)]      \
+                                             : ospf6_path_type_json[0])
 
 #define OSPF6_ROUTE_ADDRESS_STR "Display the route bestmatches the address\n"
 #define OSPF6_ROUTE_PREFIX_STR  "Display the route\n"
@@ -326,11 +330,14 @@ extern void ospf6_route_table_delete(struct ospf6_route_table *table);
 extern void ospf6_route_dump(struct ospf6_route_table *table);
 
 
-extern void ospf6_route_show(struct vty *vty, struct ospf6_route *route);
-extern void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route);
+extern void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
+                            json_object *json, bool use_json);
+extern void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
+                                   json_object *json, bool use_json);
+
 
 extern int ospf6_route_table_show(struct vty *, int, int, struct cmd_token **,
-                                 struct ospf6_route_table *);
+                                 struct ospf6_route_table *, bool use_json);
 extern int ospf6_linkstate_table_show(struct vty *vty, int idx_ipv4, int argc,
                                      struct cmd_token **argv,
                                      struct ospf6_route_table *table);
index 7b4ed84d53849cf160e4fbd006c1525dfa739fb4..212f59965d6ab549deefb61853777025f263c6ca 100644 (file)
@@ -51,6 +51,7 @@
 #include "ospf6_intra.h"
 #include "ospf6_spf.h"
 #include "ospf6d.h"
+#include "lib/json.h"
 
 DEFINE_QOBJ_TYPE(ospf6)
 
@@ -1165,7 +1166,7 @@ DEFUN(show_ipv6_ospf6,
 
 DEFUN (show_ipv6_ospf6_route,
        show_ipv6_ospf6_route_cmd,
-       "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>]",
+       "show ipv6 ospf6 route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]",
        SHOW_STR
        IP6_STR
        OSPF6_STR
@@ -1177,41 +1178,44 @@ DEFUN (show_ipv6_ospf6_route,
        "Specify IPv6 address\n"
        "Specify IPv6 prefix\n"
        "Detailed information\n"
-       "Summary of route table\n")
+       "Summary of route table\n"
+       JSON_STR)
 {
        struct ospf6 *ospf6;
+       bool uj = use_json(argc, argv);
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
 
-       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
+       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_ipv6_ospf6_route_match,
        show_ipv6_ospf6_route_match_cmd,
-       "show ipv6 ospf6 route X:X::X:X/M <match|longer>",
+       "show ipv6 ospf6 route X:X::X:X/M <match|longer> [json]",
        SHOW_STR
        IP6_STR
        OSPF6_STR
        ROUTE_STR
        "Specify IPv6 prefix\n"
        "Display routes which match the specified route\n"
-       "Display routes longer than the specified route\n")
+       "Display routes longer than the specified route\n"
+       JSON_STR)
 {
        struct ospf6 *ospf6;
+       bool uj = use_json(argc, argv);
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
 
-       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
-
+       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_ipv6_ospf6_route_match_detail,
        show_ipv6_ospf6_route_match_detail_cmd,
-       "show ipv6 ospf6 route X:X::X:X/M match detail",
+       "show ipv6 ospf6 route X:X::X:X/M match detail [json]",
        SHOW_STR
        IP6_STR
        OSPF6_STR
@@ -1219,21 +1223,22 @@ DEFUN (show_ipv6_ospf6_route_match_detail,
        "Specify IPv6 prefix\n"
        "Display routes which match the specified route\n"
        "Detailed information\n"
-       )
+       JSON_STR)
 {
        struct ospf6 *ospf6;
+       bool uj = use_json(argc, argv);
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
 
-       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
+       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table, uj);
        return CMD_SUCCESS;
 }
 
 
 DEFUN (show_ipv6_ospf6_route_type_detail,
        show_ipv6_ospf6_route_type_detail_cmd,
-       "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail",
+       "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail [json]",
        SHOW_STR
        IP6_STR
        OSPF6_STR
@@ -1243,14 +1248,15 @@ DEFUN (show_ipv6_ospf6_route_type_detail,
        "Display Type-1 External routes\n"
        "Display Type-2 External routes\n"
        "Detailed information\n"
-       )
+       JSON_STR)
 {
        struct ospf6 *ospf6;
+       bool uj = use_json(argc, argv);
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
 
-       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
+       ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table, uj);
        return CMD_SUCCESS;
 }
 
index 02eb4baf8dca479e241d1041fc5ee1942f2679ce..8d9c85fd08288de5f7167e59e6eba6c3230cfde6 100644 (file)
@@ -1006,7 +1006,7 @@ DEFUN (show_ipv6_ospf6_border_routers,
                if (strmatch(argv[idx_ipv4]->text, "detail")) {
                        for (ro = ospf6_route_head(ospf6->brouter_table); ro;
                             ro = ospf6_route_next(ro))
-                               ospf6_route_show_detail(vty, ro);
+                               ospf6_route_show_detail(vty, ro, NULL, false);
                } else {
                        inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
 
@@ -1019,7 +1019,7 @@ DEFUN (show_ipv6_ospf6_border_routers,
                                return CMD_SUCCESS;
                        }
 
-                       ospf6_route_show_detail(vty, ro);
+                       ospf6_route_show_detail(vty, ro, NULL, false);
                        return CMD_SUCCESS;
                }
        } else {