From eacd0828d4a95684fbf691e28730b229c5a8b799 Mon Sep 17 00:00:00 2001 From: Yash Ranjan Date: Wed, 28 Oct 2020 03:51:39 -0700 Subject: [PATCH] ospf6d: Json support added for command "show ipv6 ospf6 route [json]" Modify code to add JSON format output in show command "show ipv6 ospf6 route []" with proper formating Signed-off-by: Yash Ranjan --- doc/user/ospf6d.rst | 15 ++ ospf6d/ospf6_interface.c | 6 +- ospf6d/ospf6_route.c | 381 +++++++++++++++++++++++++++++++-------- ospf6d/ospf6_route.h | 13 +- ospf6d/ospf6_top.c | 32 ++-- ospf6d/ospf6d.c | 4 +- 6 files changed, 352 insertions(+), 99 deletions(-) diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index b00bdb3ab8..9d1c2e0b9d 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -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 [] [json] +.. clicmd:: show ipv6 ospf6 route [] [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 ============================ diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 948880a4b5..fd58789212 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -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; diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 60c208437b..b77f968179 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -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); diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index e2118003d5..a791a82cd4 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -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); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 7b4ed84d53..212f59965d 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -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 []", + "show ipv6 ospf6 route [] [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 ", + "show ipv6 ospf6 route X:X::X:X/M [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 detail", + "show ipv6 ospf6 route 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; } diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index 02eb4baf8d..8d9c85fd08 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -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 { -- 2.39.5