summaryrefslogtreecommitdiff
path: root/ospf6d
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_abr.c119
-rw-r--r--ospf6d/ospf6_asbr.c94
-rw-r--r--ospf6d/ospf6_flood.c12
-rw-r--r--ospf6d/ospf6_interface.c22
-rw-r--r--ospf6d/ospf6_interface.h1
-rw-r--r--ospf6d/ospf6_intra.c205
-rw-r--r--ospf6d/ospf6_lsa.c238
-rw-r--r--ospf6d/ospf6_lsa.h20
-rw-r--r--ospf6d/ospf6_lsdb.c49
-rw-r--r--ospf6d/ospf6_lsdb.h3
-rw-r--r--ospf6d/ospf6_route.c381
-rw-r--r--ospf6d/ospf6_route.h13
-rw-r--r--ospf6d/ospf6_spf.c7
-rw-r--r--ospf6d/ospf6_spf.h1
-rw-r--r--ospf6d/ospf6_top.c170
-rw-r--r--ospf6d/ospf6_top.h5
-rw-r--r--ospf6d/ospf6_zebra.c9
-rw-r--r--ospf6d/ospf6d.c770
18 files changed, 1241 insertions, 878 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 8cfdf2642c..abcdb40547 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -160,35 +160,22 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
&& route->type != OSPF6_DEST_TYPE_RANGE
&& ((route->type != OSPF6_DEST_TYPE_ROUTER)
|| !CHECK_FLAG(route->path.router_bits, OSPF6_ROUTER_BIT_E))) {
-#if 0
- zlog_debug(
- "Route type is none of network, range nor ASBR, ignore");
-#endif
return 0;
}
/* AS External routes are never considered */
if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1
|| route->path.type == OSPF6_PATH_TYPE_EXTERNAL2) {
-#if 0
- zlog_debug("Path type is external, skip");
-#endif
return 0;
}
/* do not generate if the path's area is the same as target area */
if (route->path.area_id == area->area_id) {
-#if 0
- zlog_debug("The route is in the area itself, ignore");
-#endif
return 0;
}
/* do not generate if the nexthops belongs to the target area */
if (ospf6_abr_nexthops_belong_to_area(route, area)) {
-#if 0
- zlog_debug("The route's nexthop is in the same area, ignore");
-#endif
return 0;
}
@@ -770,6 +757,10 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route,
void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old,
struct ospf6_route_table *table)
{
+ if (IS_OSPF6_DEBUG_ABR)
+ zlog_debug("%s: route %pFX, paths %d", __func__, &old->prefix,
+ listcount(old->paths));
+
if (listcount(old->paths) > 1) {
struct listnode *anode, *anext, *nnode, *rnode, *rnext;
struct ospf6_path *o_path;
@@ -778,13 +769,15 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old,
for (ALL_LIST_ELEMENTS(old->paths, anode, anext, o_path)) {
if (o_path->origin.adv_router != lsa->header->adv_router
- && o_path->origin.id != lsa->header->id)
+ || o_path->origin.id != lsa->header->id)
continue;
for (ALL_LIST_ELEMENTS_RO(o_path->nh_list, nnode, nh)) {
for (ALL_LIST_ELEMENTS(old->nh_list,
rnode, rnext, rnh)) {
if (!ospf6_nexthop_is_same(rnh, nh))
continue;
+ if (IS_OSPF6_DEBUG_ABR)
+ zlog_debug("deleted nexthop");
listnode_delete(old->nh_list, rnh);
ospf6_nexthop_delete(rnh);
}
@@ -847,14 +840,16 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
bool old_entry_updated = false;
struct ospf6_path *path, *o_path, *ecmp_path;
struct listnode *anode;
+ bool add_route = false;
memset(&prefix, 0, sizeof(prefix));
if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_PREFIX)) {
if (IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) {
is_debug++;
- zlog_debug("%s: Examin %s in area %s", __func__,
- lsa->name, oa->name);
+ zlog_debug("%s: LSA %s age %d in area %s", __func__,
+ lsa->name, ospf6_lsa_age_current(lsa),
+ oa->name);
}
prefix_lsa =
@@ -873,8 +868,9 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
} else if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_ROUTER)) {
if (IS_OSPF6_DEBUG_EXAMIN(INTER_ROUTER)) {
is_debug++;
- zlog_debug("%s: Examin %s in area %s", __func__,
- lsa->name, oa->name);
+ zlog_debug("%s: LSA %s age %d in area %s", __func__,
+ lsa->name, ospf6_lsa_age_current(lsa),
+ oa->name);
}
router_lsa =
@@ -898,8 +894,12 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
/* Find existing route */
route = ospf6_route_lookup(&prefix, table);
- if (route)
+ if (route) {
ospf6_route_lock(route);
+ if (is_debug)
+ zlog_debug("%s: route %pFX, paths %d", __func__,
+ &prefix, listcount(route->paths));
+ }
while (route && ospf6_route_is_prefix(&prefix, route)) {
if (route->path.area_id == oa->area_id
&& route->path.origin.type == lsa->header->type
@@ -952,6 +952,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
return;
}
+
/* (2) if the LSA is self-originated, ignore */
if (lsa->header->adv_router == oa->ospf6->router_id) {
if (is_debug)
@@ -1026,8 +1027,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
|| !CHECK_FLAG(abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B)) {
if (is_debug)
zlog_debug(
- "%s: ABR router entry does not exist, ignore",
- __func__);
+ "%s: ABR router entry %pFX does not exist, ignore",
+ __func__, &abr_prefix);
if (old) {
if (old->type == OSPF6_DEST_TYPE_ROUTER &&
oa->intra_brouter_calc) {
@@ -1040,7 +1041,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
zlog_debug(
"%s: remove old entry: %s %p ",
__func__, buf, (void *)old);
- ospf6_route_remove(old, table);
+ ospf6_abr_old_route_remove(lsa, old, table);
}
}
return;
@@ -1104,7 +1105,11 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
are identical.
*/
old = ospf6_route_lookup(&prefix, table);
-
+ if (old) {
+ if (is_debug)
+ zlog_debug("%s: found old route %pFX, paths %d",
+ __func__, &prefix, listcount(old->paths));
+ }
for (old_route = old; old_route; old_route = old_route->next) {
if (!ospf6_route_is_same(old_route, route) ||
(old_route->type != route->type) ||
@@ -1186,7 +1191,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
"%s: Update route: %s %p old cost %u new cost %u nh %u",
__func__, buf, (void *)old_route,
old_route->path.cost, route->path.cost,
- listcount(route->nh_list));
+ listcount(old_route->nh_list));
/* For Inter-Prefix route: Update RIB/FIB,
* For Inter-Router trigger summary update
@@ -1199,10 +1204,19 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
break;
}
+ /* If the old entry is not updated and old entry not found or old entry
+ * does not match with the new entry then add the new route
+ */
if (old_entry_updated == false) {
+ if ((old == NULL) || (old->type != route->type)
+ || (old->path.type != route->path.type))
+ add_route = true;
+ }
+
+ if (add_route) {
if (is_debug) {
zlog_debug(
- "%s: Install route: %s cost %u nh %u adv_router %pI4",
+ "%s: Install new route: %s cost %u nh %u adv_router %pI4",
__func__, buf, route->path.cost,
listcount(route->nh_list),
&route->path.origin.adv_router);
@@ -1296,7 +1310,9 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
}
static int ospf6_inter_area_prefix_lsa_show(struct vty *vty,
- struct ospf6_lsa *lsa)
+ struct ospf6_lsa *lsa,
+ json_object *json_obj,
+ bool use_json)
{
struct ospf6_inter_prefix_lsa *prefix_lsa;
char buf[INET6_ADDRSTRLEN];
@@ -1304,16 +1320,29 @@ static int ospf6_inter_area_prefix_lsa_show(struct vty *vty,
prefix_lsa = (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END(
lsa->header);
- vty_out(vty, " Metric: %lu\n",
- (unsigned long)OSPF6_ABR_SUMMARY_METRIC(prefix_lsa));
+ if (use_json) {
+ json_object_int_add(
+ json_obj, "metric",
+ (unsigned long)OSPF6_ABR_SUMMARY_METRIC(prefix_lsa));
+ ospf6_prefix_options_printbuf(prefix_lsa->prefix.prefix_options,
+ buf, sizeof(buf));
+ json_object_string_add(json_obj, "prefixOptions", buf);
+ json_object_string_add(
+ json_obj, "prefix",
+ ospf6_inter_area_prefix_lsa_get_prefix_str(
+ lsa, buf, sizeof(buf), 0));
+ } else {
+ vty_out(vty, " Metric: %lu\n",
+ (unsigned long)OSPF6_ABR_SUMMARY_METRIC(prefix_lsa));
- ospf6_prefix_options_printbuf(prefix_lsa->prefix.prefix_options, buf,
- sizeof(buf));
- vty_out(vty, " Prefix Options: %s\n", buf);
+ ospf6_prefix_options_printbuf(prefix_lsa->prefix.prefix_options,
+ buf, sizeof(buf));
+ vty_out(vty, " Prefix Options: %s\n", buf);
- vty_out(vty, " Prefix: %s\n",
- ospf6_inter_area_prefix_lsa_get_prefix_str(lsa, buf,
- sizeof(buf), 0));
+ vty_out(vty, " Prefix: %s\n",
+ ospf6_inter_area_prefix_lsa_get_prefix_str(
+ lsa, buf, sizeof(buf), 0));
+ }
return 0;
}
@@ -1338,7 +1367,9 @@ static char *ospf6_inter_area_router_lsa_get_prefix_str(struct ospf6_lsa *lsa,
}
static int ospf6_inter_area_router_lsa_show(struct vty *vty,
- struct ospf6_lsa *lsa)
+ struct ospf6_lsa *lsa,
+ json_object *json_obj,
+ bool use_json)
{
struct ospf6_inter_router_lsa *router_lsa;
char buf[64];
@@ -1347,12 +1378,22 @@ static int ospf6_inter_area_router_lsa_show(struct vty *vty,
lsa->header);
ospf6_options_printbuf(router_lsa->options, buf, sizeof(buf));
- vty_out(vty, " Options: %s\n", buf);
- vty_out(vty, " Metric: %lu\n",
- (unsigned long)OSPF6_ABR_SUMMARY_METRIC(router_lsa));
+ if (use_json) {
+ json_object_string_add(json_obj, "options", buf);
+ json_object_int_add(
+ json_obj, "metric",
+ (unsigned long)OSPF6_ABR_SUMMARY_METRIC(router_lsa));
+ } else {
+ vty_out(vty, " Options: %s\n", buf);
+ vty_out(vty, " Metric: %lu\n",
+ (unsigned long)OSPF6_ABR_SUMMARY_METRIC(router_lsa));
+ }
inet_ntop(AF_INET, &router_lsa->router_id, buf, sizeof(buf));
- vty_out(vty, " Destination Router ID: %s\n", buf);
+ if (use_json)
+ json_object_string_add(json_obj, "destinationRouterId", buf);
+ else
+ vty_out(vty, " Destination Router ID: %s\n", buf);
return 0;
}
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 0e419cbff6..3449f48267 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -210,7 +210,7 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
struct ospf6_route *route,
struct ospf6 *ospf6)
{
- struct ospf6_route *old_route;
+ struct ospf6_route *old_route, *next_route;
struct ospf6_path *ecmp_path, *o_path = NULL;
struct listnode *anode, *anext;
struct listnode *nnode, *rnode, *rnext;
@@ -220,9 +220,11 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
/* check for old entry match with new route origin,
* delete old entry.
*/
- for (old_route = old; old_route; old_route = old_route->next) {
+ for (old_route = old; old_route; old_route = next_route) {
bool route_updated = false;
+ next_route = old_route->next;
+
if (!ospf6_route_is_same(old_route, route)
|| (old_route->path.type != route->path.type))
continue;
@@ -315,6 +317,8 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
old_route->path.cost,
route->path.cost);
}
+ if (old == old_route)
+ old = next_route;
ospf6_route_remove(old_route,
ospf6->route_table);
}
@@ -1439,8 +1443,7 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6,
struct ospf6_redist *red;
total = 0;
- for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
- nroute[type] = 0;
+ memset(nroute, 0, sizeof(nroute));
for (route = ospf6_route_head(ospf6->external_table); route;
route = ospf6_route_next(route)) {
info = route->route_option;
@@ -1448,12 +1451,11 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6,
total++;
}
- if (use_json)
- json_route = json_object_new_object();
- else
+ if (!use_json)
vty_out(vty, "Redistributing External Routes from:\n");
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+
red = ospf6_redist_lookup(ospf6, type, 0);
if (!red)
@@ -1462,6 +1464,7 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6,
continue;
if (use_json) {
+ json_route = json_object_new_object();
json_object_string_add(json_route, "routeType",
ZROUTE_NAME(type));
json_object_int_add(json_route, "numberOfRoutes",
@@ -1890,7 +1893,8 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa,
return (buf);
}
-static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
struct ospf6_as_external_lsa *external;
char buf[64];
@@ -1908,31 +1912,65 @@ static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
(CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T'
: '-'));
- vty_out(vty, " Bits: %s\n", buf);
- vty_out(vty, " Metric: %5lu\n",
- (unsigned long)OSPF6_ASBR_METRIC(external));
-
- ospf6_prefix_options_printbuf(external->prefix.prefix_options, buf,
- sizeof(buf));
- vty_out(vty, " Prefix Options: %s\n", buf);
+ if (use_json) {
+ json_object_string_add(json_obj, "bits", buf);
+ json_object_int_add(json_obj, "metric",
+ (unsigned long)OSPF6_ASBR_METRIC(external));
+ ospf6_prefix_options_printbuf(external->prefix.prefix_options,
+ buf, sizeof(buf));
+ json_object_string_add(json_obj, "prefixOptions", buf);
+ json_object_int_add(
+ json_obj, "referenceLsType",
+ ntohs(external->prefix.prefix_refer_lstype));
+ json_object_string_add(json_obj, "prefix",
+ ospf6_as_external_lsa_get_prefix_str(
+ lsa, buf, sizeof(buf), 0));
+
+ /* Forwarding-Address */
+ json_object_boolean_add(
+ json_obj, "forwardingAddressPresent",
+ CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F));
+ if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F))
+ json_object_string_add(
+ json_obj, "forwardingAddress",
+ ospf6_as_external_lsa_get_prefix_str(
+ lsa, buf, sizeof(buf), 1));
+
+ /* Tag */
+ json_object_boolean_add(
+ json_obj, "tagPresent",
+ CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T));
+ if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T))
+ json_object_int_add(json_obj, "tag",
+ ospf6_as_external_lsa_get_tag(lsa));
+ } else {
+ vty_out(vty, " Bits: %s\n", buf);
+ vty_out(vty, " Metric: %5lu\n",
+ (unsigned long)OSPF6_ASBR_METRIC(external));
- vty_out(vty, " Referenced LSType: %d\n",
- ntohs(external->prefix.prefix_refer_lstype));
+ ospf6_prefix_options_printbuf(external->prefix.prefix_options,
+ buf, sizeof(buf));
+ vty_out(vty, " Prefix Options: %s\n", buf);
- vty_out(vty, " Prefix: %s\n",
- ospf6_as_external_lsa_get_prefix_str(lsa, buf, sizeof(buf), 0));
+ vty_out(vty, " Referenced LSType: %d\n",
+ ntohs(external->prefix.prefix_refer_lstype));
- /* Forwarding-Address */
- if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F)) {
- vty_out(vty, " Forwarding-Address: %s\n",
+ vty_out(vty, " Prefix: %s\n",
ospf6_as_external_lsa_get_prefix_str(lsa, buf,
- sizeof(buf), 1));
- }
+ sizeof(buf), 0));
- /* Tag */
- if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) {
- vty_out(vty, " Tag: %" ROUTE_TAG_PRI "\n",
- ospf6_as_external_lsa_get_tag(lsa));
+ /* Forwarding-Address */
+ if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F)) {
+ vty_out(vty, " Forwarding-Address: %s\n",
+ ospf6_as_external_lsa_get_prefix_str(
+ lsa, buf, sizeof(buf), 1));
+ }
+
+ /* Tag */
+ if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) {
+ vty_out(vty, " Tag: %" ROUTE_TAG_PRI "\n",
+ ospf6_as_external_lsa_get_tag(lsa));
+ }
}
return 0;
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 0662cfd683..2d896546fa 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -452,12 +452,6 @@ void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
&& oi != OSPF6_INTERFACE(lsa->lsdb->data))
continue;
-#if 0
- if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
- ospf6_is_interface_virtual_link (oi))
- continue;
-#endif /*0*/
-
ospf6_flood_interface(from, lsa, oi);
}
}
@@ -527,12 +521,6 @@ static void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
&& oi != OSPF6_INTERFACE(lsa->lsdb->data))
continue;
-#if 0
- if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
- ospf6_is_interface_virtual_link (oi))
- continue;
-#endif /*0*/
-
ospf6_flood_clear_interface(lsa, oi);
}
}
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 4988cee7d8..0cc3bd2cc9 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -250,6 +250,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
THREAD_OFF(oi->thread_send_lsupdate);
THREAD_OFF(oi->thread_send_lsack);
THREAD_OFF(oi->thread_sso);
+ THREAD_OFF(oi->thread_wait_timer);
ospf6_lsdb_remove_all(oi->lsdb);
ospf6_lsdb_remove_all(oi->lsupdate_list);
@@ -304,6 +305,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi)
THREAD_OFF(oi->thread_link_lsa);
THREAD_OFF(oi->thread_intra_prefix_lsa);
THREAD_OFF(oi->thread_as_extern_lsa);
+ THREAD_OFF(oi->thread_wait_timer);
}
static struct in6_addr *
@@ -793,7 +795,7 @@ int interface_up(struct thread *thread)
else {
ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi);
thread_add_timer(master, wait_timer, oi, oi->dead_interval,
- NULL);
+ &oi->thread_wait_timer);
}
return 0;
@@ -1414,7 +1416,7 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
[<\
detail\
|<X:X::X:X|X:X::X:X/M> [<match|detail>]\
- >]",
+ >] [json]",
SHOW_STR
IP6_STR
OSPF6_STR
@@ -1425,12 +1427,14 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR
OSPF6_ROUTE_MATCH_STR
- "Display details of the prefixes\n")
+ "Display details of the prefixes\n"
+ JSON_STR)
{
int idx_ifname = 4;
int idx_prefix = 6;
struct interface *ifp;
struct ospf6_interface *oi;
+ bool uj = use_json(argc, argv);
ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
if (ifp == NULL) {
@@ -1445,8 +1449,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,
+ uj);
return CMD_SUCCESS;
}
@@ -1457,7 +1461,7 @@ DEFUN (show_ipv6_ospf6_interface_prefix,
[<\
detail\
|<X:X::X:X|X:X::X:X/M> [<match|detail>]\
- >]",
+ >] [json]",
SHOW_STR
IP6_STR
OSPF6_STR
@@ -1467,12 +1471,14 @@ DEFUN (show_ipv6_ospf6_interface_prefix,
OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR
OSPF6_ROUTE_MATCH_STR
- "Display details of the prefixes\n")
+ "Display details of the prefixes\n"
+ JSON_STR)
{
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
int idx_prefix = 5;
struct ospf6_interface *oi;
struct interface *ifp;
+ bool uj = use_json(argc, argv);
FOR_ALL_INTERFACES (vrf, ifp) {
oi = (struct ospf6_interface *)ifp->info;
@@ -1480,7 +1486,7 @@ DEFUN (show_ipv6_ospf6_interface_prefix,
continue;
ospf6_route_table_show(vty, idx_prefix, argc, argv,
- oi->route_connected);
+ oi->route_connected, uj);
}
return CMD_SUCCESS;
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index dd7f4d1b1e..6e4692920c 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -111,6 +111,7 @@ struct ospf6_interface {
struct thread *thread_link_lsa;
struct thread *thread_intra_prefix_lsa;
struct thread *thread_as_extern_lsa;
+ struct thread *thread_wait_timer;
struct ospf6_route_table *route_connected;
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 17538c466a..2abe64ac60 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -76,7 +76,8 @@ static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf,
*)(start
+ pos * (sizeof(struct
ospf6_router_lsdesc)));
- if ((char *)lsdesc < end) {
+ if ((char *)lsdesc + sizeof(struct ospf6_router_lsdesc)
+ <= end) {
if (buf && (buflen > INET_ADDRSTRLEN * 2)) {
inet_ntop(AF_INET,
&lsdesc->neighbor_interface_id, buf1,
@@ -84,20 +85,24 @@ static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf,
inet_ntop(AF_INET, &lsdesc->neighbor_router_id,
buf2, sizeof(buf2));
sprintf(buf, "%s/%s", buf2, buf1);
+
+ return buf;
}
- } else
- return NULL;
+ }
}
- return buf;
+ return NULL;
}
-static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
char *start, *end, *current;
char buf[32], name[32], bits[16], options[32];
struct ospf6_router_lsa *router_lsa;
struct ospf6_router_lsdesc *lsdesc;
+ json_object *json_arr;
+ json_object *json_loop;
router_lsa =
(struct ospf6_router_lsa *)((char *)lsa->header
@@ -105,7 +110,12 @@ static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
ospf6_capability_printbuf(router_lsa->bits, bits, sizeof(bits));
ospf6_options_printbuf(router_lsa->options, options, sizeof(options));
- vty_out(vty, " Bits: %s Options: %s\n", bits, options);
+ if (use_json) {
+ json_object_string_add(json_obj, "bits", bits);
+ json_object_string_add(json_obj, "options", options);
+ json_arr = json_object_new_array();
+ } else
+ vty_out(vty, " Bits: %s Options: %s\n", bits, options);
start = (char *)router_lsa + sizeof(struct ospf6_router_lsa);
end = (char *)lsa->header + ntohs(lsa->header->length);
@@ -126,18 +136,43 @@ static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
snprintf(name, sizeof(name), "Unknown (%#x)",
lsdesc->type);
- vty_out(vty, " Type: %s Metric: %d\n", name,
- ntohs(lsdesc->metric));
- vty_out(vty, " Interface ID: %s\n",
- inet_ntop(AF_INET, &lsdesc->interface_id, buf,
- sizeof(buf)));
- vty_out(vty, " Neighbor Interface ID: %s\n",
- inet_ntop(AF_INET, &lsdesc->neighbor_interface_id, buf,
- sizeof(buf)));
- vty_out(vty, " Neighbor Router ID: %s\n",
- inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf,
- sizeof(buf)));
+ if (use_json) {
+ json_loop = json_object_new_object();
+ json_object_string_add(json_loop, "type", name);
+ json_object_int_add(json_loop, "metric",
+ ntohs(lsdesc->metric));
+ json_object_string_add(json_loop, "interfaceId",
+ inet_ntop(AF_INET,
+ &lsdesc->interface_id,
+ buf, sizeof(buf)));
+ json_object_string_add(
+ json_loop, "neighborInterfaceId",
+ inet_ntop(AF_INET,
+ &lsdesc->neighbor_interface_id, buf,
+ sizeof(buf)));
+ json_object_string_add(
+ json_loop, "neighborRouterId",
+ inet_ntop(AF_INET, &lsdesc->neighbor_router_id,
+ buf, sizeof(buf)));
+ json_object_array_add(json_arr, json_loop);
+ } else {
+ vty_out(vty, " Type: %s Metric: %d\n", name,
+ ntohs(lsdesc->metric));
+ vty_out(vty, " Interface ID: %s\n",
+ inet_ntop(AF_INET, &lsdesc->interface_id, buf,
+ sizeof(buf)));
+ vty_out(vty, " Neighbor Interface ID: %s\n",
+ inet_ntop(AF_INET,
+ &lsdesc->neighbor_interface_id, buf,
+ sizeof(buf)));
+ vty_out(vty, " Neighbor Router ID: %s\n",
+ inet_ntop(AF_INET, &lsdesc->neighbor_router_id,
+ buf, sizeof(buf)));
+ }
}
+ if (use_json)
+ json_object_object_add(json_obj, "lsaDescription", json_arr);
+
return 0;
}
@@ -411,39 +446,55 @@ static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa *lsa, char *buf,
if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) {
lsdesc = (struct ospf6_network_lsdesc *)current;
- if (buf)
+ if (buf) {
inet_ntop(AF_INET, &lsdesc->router_id, buf,
buflen);
- } else
- return NULL;
+ return buf;
+ }
+ }
}
- return (buf);
+ return NULL;
}
-static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
char *start, *end, *current;
struct ospf6_network_lsa *network_lsa;
struct ospf6_network_lsdesc *lsdesc;
char buf[128], options[32];
+ json_object *json_arr;
network_lsa =
(struct ospf6_network_lsa *)((caddr_t)lsa->header
+ sizeof(struct ospf6_lsa_header));
ospf6_options_printbuf(network_lsa->options, options, sizeof(options));
- vty_out(vty, " Options: %s\n", options);
+ if (use_json)
+ json_object_string_add(json_obj, "options", options);
+ else
+ vty_out(vty, " Options: %s\n", options);
start = (char *)network_lsa + sizeof(struct ospf6_network_lsa);
end = (char *)lsa->header + ntohs(lsa->header->length);
+ if (use_json)
+ json_arr = json_object_new_array();
+
for (current = start;
current + sizeof(struct ospf6_network_lsdesc) <= end;
current += sizeof(struct ospf6_network_lsdesc)) {
lsdesc = (struct ospf6_network_lsdesc *)current;
inet_ntop(AF_INET, &lsdesc->router_id, buf, sizeof(buf));
- vty_out(vty, " Attached Router: %s\n", buf);
+ if (use_json)
+ json_object_array_add(json_arr,
+ json_object_new_string(buf));
+ else
+ vty_out(vty, " Attached Router: %s\n", buf);
}
+ if (use_json)
+ json_object_object_add(json_obj, "attachedRouter", json_arr);
+
return 0;
}
@@ -602,7 +653,7 @@ static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
end = (char *)lsa->header + ntohs(lsa->header->length);
current = start;
- do {
+ while (current + sizeof(struct ospf6_prefix) <= end) {
prefix = (struct ospf6_prefix *)current;
if (prefix->prefix_length == 0
|| current + OSPF6_PREFIX_SIZE(prefix) > end) {
@@ -620,12 +671,13 @@ static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
inet_ntop(AF_INET6, &in6, buf, buflen);
return (buf);
}
- } while (current <= end);
+ }
}
return NULL;
}
-static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
char *start, *end, *current;
struct ospf6_link_lsa *link_lsa;
@@ -634,6 +686,10 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
struct ospf6_prefix *prefix;
const char *p, *mc, *la, *nu;
struct in6_addr in6;
+ json_object *json_loop;
+ json_object *json_arr = NULL;
+ char str[15];
+ char prefix_string[133];
link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa->header
+ sizeof(struct ospf6_lsa_header));
@@ -642,10 +698,18 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf));
prefixnum = ntohl(link_lsa->prefix_num);
- vty_out(vty, " Priority: %d Options: %s\n", link_lsa->priority,
- options);
- vty_out(vty, " LinkLocal Address: %s\n", buf);
- vty_out(vty, " Number of Prefix: %d\n", prefixnum);
+ if (use_json) {
+ json_arr = json_object_new_array();
+ json_object_int_add(json_obj, "priority", link_lsa->priority);
+ json_object_string_add(json_obj, "options", options);
+ json_object_string_add(json_obj, "linkLocalAddress", buf);
+ json_object_int_add(json_obj, "numberOfPrefix", prefixnum);
+ } else {
+ vty_out(vty, " Priority: %d Options: %s\n",
+ link_lsa->priority, options);
+ vty_out(vty, " LinkLocal Address: %s\n", buf);
+ vty_out(vty, " Number of Prefix: %d\n", prefixnum);
+ }
start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
end = (char *)lsa->header + ntohs(lsa->header->length);
@@ -668,16 +732,31 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU)
? "NU"
: "--");
- vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la,
- nu);
+ if (use_json) {
+ json_loop = json_object_new_object();
+ snprintf(str, sizeof(str), "%s|%s|%s|%s", p, mc, la,
+ nu);
+ json_object_string_add(json_loop, "prefixOption", str);
+ } else
+ vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p,
+ mc, la, nu);
memset(&in6, 0, sizeof(in6));
memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
OSPF6_PREFIX_SPACE(prefix->prefix_length));
inet_ntop(AF_INET6, &in6, buf, sizeof(buf));
- vty_out(vty, " Prefix: %s/%d\n", buf,
- prefix->prefix_length);
+ if (use_json) {
+ snprintf(prefix_string, sizeof(prefix_string), "%s/%d",
+ buf, prefix->prefix_length);
+ json_object_string_add(json_loop, "prefix",
+ prefix_string);
+ json_object_array_add(json_arr, json_loop);
+ } else
+ vty_out(vty, " Prefix: %s/%d\n", buf,
+ prefix->prefix_length);
}
+ if (use_json)
+ json_object_object_add(json_obj, "prefix", json_arr);
return 0;
}
@@ -803,7 +882,7 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
end = (char *)lsa->header + ntohs(lsa->header->length);
current = start;
- do {
+ while (current + sizeof(struct ospf6_prefix) <= end) {
prefix = (struct ospf6_prefix *)current;
if (prefix->prefix_length == 0
|| current + OSPF6_PREFIX_SIZE(prefix) > end) {
@@ -823,12 +902,13 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
prefix->prefix_length);
return (buf);
}
- } while (current <= end);
+ }
}
- return (buf);
+ return NULL;
}
-static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
char *start, *end, *current;
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
@@ -838,6 +918,10 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
char id[16], adv_router[16];
const char *p, *mc, *la, *nu;
struct in6_addr in6;
+ json_object *json_loop;
+ json_object *json_arr = NULL;
+ char str[15];
+ char prefix_string[133];
intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
*)((caddr_t)lsa->header
@@ -845,13 +929,25 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
prefixnum = ntohs(intra_prefix_lsa->prefix_num);
- vty_out(vty, " Number of Prefix: %d\n", prefixnum);
+ if (use_json) {
+ json_arr = json_object_new_array();
+ json_object_int_add(json_obj, "numberOfPrefix", prefixnum);
+ } else
+ vty_out(vty, " Number of Prefix: %d\n", prefixnum);
inet_ntop(AF_INET, &intra_prefix_lsa->ref_id, id, sizeof(id));
inet_ntop(AF_INET, &intra_prefix_lsa->ref_adv_router, adv_router,
sizeof(adv_router));
- vty_out(vty, " Reference: %s Id: %s Adv: %s\n",
- ospf6_lstype_name(intra_prefix_lsa->ref_type), id, adv_router);
+ if (use_json) {
+ json_object_string_add(
+ json_obj, "reference",
+ ospf6_lstype_name(intra_prefix_lsa->ref_type));
+ json_object_string_add(json_obj, "referenceId", id);
+ json_object_string_add(json_obj, "referenceAdv", adv_router);
+ } else
+ vty_out(vty, " Reference: %s Id: %s Adv: %s\n",
+ ospf6_lstype_name(intra_prefix_lsa->ref_type), id,
+ adv_router);
start = (char *)intra_prefix_lsa
+ sizeof(struct ospf6_intra_prefix_lsa);
@@ -875,16 +971,31 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU)
? "NU"
: "--");
- vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la,
- nu);
+ if (use_json) {
+ json_loop = json_object_new_object();
+ snprintf(str, sizeof(str), "%s|%s|%s|%s", p, mc, la,
+ nu);
+ json_object_string_add(json_loop, "prefixOption", str);
+ } else
+ vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p,
+ mc, la, nu);
memset(&in6, 0, sizeof(in6));
memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
OSPF6_PREFIX_SPACE(prefix->prefix_length));
inet_ntop(AF_INET6, &in6, buf, sizeof(buf));
- vty_out(vty, " Prefix: %s/%d\n", buf,
- prefix->prefix_length);
+ if (use_json) {
+ snprintf(prefix_string, sizeof(prefix_string), "%s/%d",
+ buf, prefix->prefix_length);
+ json_object_string_add(json_loop, "prefix",
+ prefix_string);
+ json_object_array_add(json_arr, json_loop);
+ } else
+ vty_out(vty, " Prefix: %s/%d\n", buf,
+ prefix->prefix_length);
}
+ if (use_json)
+ json_object_object_add(json_obj, "prefix", json_arr);
return 0;
}
@@ -1338,6 +1449,8 @@ static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route,
g_route->path.origin.id = h_path->origin.id;
g_route->path.origin.adv_router =
h_path->origin.adv_router;
+ if (nroute)
+ ospf6_route_unlock(nroute);
break;
}
}
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 29141ee7f8..f1b04c9bec 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -66,7 +66,8 @@ struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa)
return ospf6;
}
-static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_obj, bool use_json)
{
uint8_t *start, *end, *current;
char byte[4];
@@ -74,18 +75,22 @@ static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
start = (uint8_t *)lsa->header + sizeof(struct ospf6_lsa_header);
end = (uint8_t *)lsa->header + ntohs(lsa->header->length);
- vty_out(vty, " Unknown contents:\n");
- for (current = start; current < end; current++) {
- if ((current - start) % 16 == 0)
- vty_out(vty, "\n ");
- else if ((current - start) % 4 == 0)
- vty_out(vty, " ");
+ if (use_json)
+ json_object_string_add(json_obj, "LsaType", "unknown");
+ else {
+ vty_out(vty, " Unknown contents:\n");
+ for (current = start; current < end; current++) {
+ if ((current - start) % 16 == 0)
+ vty_out(vty, "\n ");
+ else if ((current - start) % 4 == 0)
+ vty_out(vty, " ");
+
+ snprintf(byte, sizeof(byte), "%02x", *current);
+ vty_out(vty, "%s", byte);
+ }
- snprintf(byte, sizeof(byte), "%02x", *current);
- vty_out(vty, "%s", byte);
+ vty_out(vty, "\n\n");
}
-
- vty_out(vty, "\n\n");
return 0;
}
@@ -392,13 +397,15 @@ void ospf6_lsa_show_summary_header(struct vty *vty)
"AdvRouter", "Age", "SeqNum", "Payload");
}
-void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa)
+void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_array, bool use_json)
{
char adv_router[16], id[16];
int type;
const struct ospf6_lsa_handler *handler;
- char buf[64], tmpbuf[80];
+ char buf[64];
int cnt = 0;
+ json_object *json_obj = NULL;
assert(lsa);
assert(lsa->header);
@@ -409,34 +416,95 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa)
type = ntohs(lsa->header->type);
handler = ospf6_get_lsa_handler(lsa->header->type);
+
+ if (use_json)
+ json_obj = json_object_new_object();
+
if ((type == OSPF6_LSTYPE_INTER_PREFIX)
|| (type == OSPF6_LSTYPE_INTER_ROUTER)
|| (type == OSPF6_LSTYPE_AS_EXTERNAL)) {
- vty_out(vty, "%-4s %-15s%-15s%4hu %8lx %30s\n",
- ospf6_lstype_short_name(lsa->header->type), id,
- adv_router, ospf6_lsa_age_current(lsa),
- (unsigned long)ntohl(lsa->header->seqnum),
- handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0));
+ if (use_json) {
+ json_object_string_add(
+ json_obj, "type",
+ ospf6_lstype_short_name(lsa->header->type));
+ json_object_string_add(json_obj, "lsId", id);
+ json_object_string_add(json_obj, "advRouter",
+ adv_router);
+ json_object_int_add(json_obj, "age",
+ ospf6_lsa_age_current(lsa));
+ json_object_int_add(
+ json_obj, "seqNum",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ json_object_string_add(
+ json_obj, "payload",
+ handler->lh_get_prefix_str(lsa, buf,
+ sizeof(buf), 0));
+ json_object_array_add(json_array, json_obj);
+ } else
+ vty_out(vty, "%-4s %-15s%-15s%4hu %8lx %30s\n",
+ ospf6_lstype_short_name(lsa->header->type), id,
+ adv_router, ospf6_lsa_age_current(lsa),
+ (unsigned long)ntohl(lsa->header->seqnum),
+ handler->lh_get_prefix_str(lsa, buf,
+ sizeof(buf), 0));
} else if (type != OSPF6_LSTYPE_UNKNOWN) {
- snprintf(tmpbuf, sizeof(tmpbuf), "%-4s %-15s%-15s%4hu %8lx",
- ospf6_lstype_short_name(lsa->header->type), id,
- adv_router, ospf6_lsa_age_current(lsa),
- (unsigned long)ntohl(lsa->header->seqnum));
-
while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt)
!= NULL) {
- vty_out(vty, "%s %30s\n", tmpbuf, buf);
+ if (use_json) {
+ json_object_string_add(
+ json_obj, "type",
+ ospf6_lstype_short_name(
+ lsa->header->type));
+ json_object_string_add(json_obj, "lsId", id);
+ json_object_string_add(json_obj, "advRouter",
+ adv_router);
+ json_object_int_add(json_obj, "age",
+ ospf6_lsa_age_current(lsa));
+ json_object_int_add(
+ json_obj, "seqNum",
+ (unsigned long)ntohl(
+ lsa->header->seqnum));
+ json_object_string_add(json_obj, "payload",
+ buf);
+ json_object_array_add(json_array, json_obj);
+ json_obj = json_object_new_object();
+ } else
+ vty_out(vty, "%-4s %-15s%-15s%4hu %8lx %30s\n",
+ ospf6_lstype_short_name(
+ lsa->header->type),
+ id, adv_router,
+ ospf6_lsa_age_current(lsa),
+ (unsigned long)ntohl(
+ lsa->header->seqnum),
+ buf);
cnt++;
}
+ if (use_json)
+ json_object_free(json_obj);
} else {
- vty_out(vty, "%-4s %-15s%-15s%4hu %8lx\n",
- ospf6_lstype_short_name(lsa->header->type), id,
- adv_router, ospf6_lsa_age_current(lsa),
- (unsigned long)ntohl(lsa->header->seqnum));
+ if (use_json) {
+ json_object_string_add(
+ json_obj, "type",
+ ospf6_lstype_short_name(lsa->header->type));
+ json_object_string_add(json_obj, "lsId", id);
+ json_object_string_add(json_obj, "advRouter",
+ adv_router);
+ json_object_int_add(json_obj, "age",
+ ospf6_lsa_age_current(lsa));
+ json_object_int_add(
+ json_obj, "seqNum",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ json_object_array_add(json_array, json_obj);
+ } else
+ vty_out(vty, "%-4s %-15s%-15s%4hu %8lx\n",
+ ospf6_lstype_short_name(lsa->header->type), id,
+ adv_router, ospf6_lsa_age_current(lsa),
+ (unsigned long)ntohl(lsa->header->seqnum));
}
}
-void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa)
+void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_array, bool use_json)
{
uint8_t *start, *end, *current;
char byte[4];
@@ -444,6 +512,9 @@ void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa)
start = (uint8_t *)lsa->header;
end = (uint8_t *)lsa->header + ntohs(lsa->header->length);
+ if (use_json)
+ return;
+
vty_out(vty, "\n");
vty_out(vty, "%s:\n", lsa->name);
@@ -458,12 +529,15 @@ void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa)
}
vty_out(vty, "\n\n");
+
return;
}
-void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa)
+void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_array, bool use_json)
{
char adv_router[64], id[64];
+ json_object *json_obj;
assert(lsa && lsa->header);
@@ -471,30 +545,56 @@ void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa)
inet_ntop(AF_INET, &lsa->header->adv_router, adv_router,
sizeof(adv_router));
- vty_out(vty, "\n");
- vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa),
- ospf6_lstype_name(lsa->header->type));
- vty_out(vty, "Link State ID: %s\n", id);
- vty_out(vty, "Advertising Router: %s\n", adv_router);
- vty_out(vty, "LS Sequence Number: %#010lx\n",
- (unsigned long)ntohl(lsa->header->seqnum));
- vty_out(vty, "CheckSum: %#06hx Length: %hu\n",
- ntohs(lsa->header->checksum), ntohs(lsa->header->length));
- vty_out(vty, "Flag: %x \n", lsa->flag);
- vty_out(vty, "Lock: %d \n", lsa->lock);
- vty_out(vty, "ReTx Count: %d\n", lsa->retrans_count);
- vty_out(vty, "Threads: Expire: 0x%p, Refresh: 0x%p \n",
- (void *)lsa->expire, (void *)lsa->refresh);
- vty_out(vty, "\n");
+ if (use_json) {
+ json_obj = json_object_new_object();
+ json_object_int_add(json_obj, "age",
+ ospf6_lsa_age_current(lsa));
+ json_object_string_add(json_obj, "type",
+ ospf6_lstype_name(lsa->header->type));
+ json_object_string_add(json_obj, "linkStateId", id);
+ json_object_string_add(json_obj, "advertisingRouter",
+ adv_router);
+ json_object_int_add(json_obj, "lsSequenceNumber",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ json_object_int_add(json_obj, "checksum",
+ ntohs(lsa->header->checksum));
+ json_object_int_add(json_obj, "length",
+ ntohs(lsa->header->length));
+ json_object_int_add(json_obj, "flag", lsa->flag);
+ json_object_int_add(json_obj, "lock", lsa->lock);
+ json_object_int_add(json_obj, "reTxCount", lsa->retrans_count);
+
+ /* Threads Data not added */
+ json_object_array_add(json_array, json_obj);
+ } else {
+ vty_out(vty, "\n");
+ vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa),
+ ospf6_lstype_name(lsa->header->type));
+ vty_out(vty, "Link State ID: %s\n", id);
+ vty_out(vty, "Advertising Router: %s\n", adv_router);
+ vty_out(vty, "LS Sequence Number: %#010lx\n",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ vty_out(vty, "CheckSum: %#06hx Length: %hu\n",
+ ntohs(lsa->header->checksum),
+ ntohs(lsa->header->length));
+ vty_out(vty, "Flag: %x \n", lsa->flag);
+ vty_out(vty, "Lock: %d \n", lsa->lock);
+ vty_out(vty, "ReTx Count: %d\n", lsa->retrans_count);
+ vty_out(vty, "Threads: Expire: 0x%p, Refresh: 0x%p \n",
+ (void *)lsa->expire, (void *)lsa->refresh);
+ vty_out(vty, "\n");
+ }
return;
}
-void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
+void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json_array, bool use_json)
{
char adv_router[64], id[64];
const struct ospf6_lsa_handler *handler;
struct timeval now, res;
char duration[64];
+ json_object *json_obj = NULL;
assert(lsa && lsa->header);
@@ -505,27 +605,47 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
monotime(&now);
timersub(&now, &lsa->installed, &res);
timerstring(&res, duration, sizeof(duration));
-
- vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa),
- ospf6_lstype_name(lsa->header->type));
- vty_out(vty, "Link State ID: %s\n", id);
- vty_out(vty, "Advertising Router: %s\n", adv_router);
- vty_out(vty, "LS Sequence Number: %#010lx\n",
- (unsigned long)ntohl(lsa->header->seqnum));
- vty_out(vty, "CheckSum: %#06hx Length: %hu\n",
- ntohs(lsa->header->checksum), ntohs(lsa->header->length));
- vty_out(vty, "Duration: %s\n", duration);
+ if (use_json) {
+ json_obj = json_object_new_object();
+ json_object_int_add(json_obj, "age",
+ ospf6_lsa_age_current(lsa));
+ json_object_string_add(json_obj, "type",
+ ospf6_lstype_name(lsa->header->type));
+ json_object_string_add(json_obj, "advertisingRouter",
+ adv_router);
+ json_object_int_add(json_obj, "lsSequenceNumber",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ json_object_int_add(json_obj, "checkSum",
+ ntohs(lsa->header->checksum));
+ json_object_int_add(json_obj, "length",
+ ntohs(lsa->header->length));
+ json_object_string_add(json_obj, "duration", duration);
+ } else {
+ vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa),
+ ospf6_lstype_name(lsa->header->type));
+ vty_out(vty, "Link State ID: %s\n", id);
+ vty_out(vty, "Advertising Router: %s\n", adv_router);
+ vty_out(vty, "LS Sequence Number: %#010lx\n",
+ (unsigned long)ntohl(lsa->header->seqnum));
+ vty_out(vty, "CheckSum: %#06hx Length: %hu\n",
+ ntohs(lsa->header->checksum),
+ ntohs(lsa->header->length));
+ vty_out(vty, "Duration: %s\n", duration);
+ }
handler = ospf6_get_lsa_handler(lsa->header->type);
if (handler->lh_show != NULL)
- handler->lh_show(vty, lsa);
+ handler->lh_show(vty, lsa, json_obj, use_json);
else {
assert(unknown_handler.lh_show != NULL);
- unknown_handler.lh_show(vty, lsa);
+ unknown_handler.lh_show(vty, lsa, json_obj, use_json);
}
- vty_out(vty, "\n");
+ if (use_json)
+ json_object_array_add(json_array, json_obj);
+ else
+ vty_out(vty, "\n");
}
/* OSPFv3 LSA creation/deletion function */
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index 814e276796..7fa9c5fe40 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -21,6 +21,7 @@
#ifndef OSPF6_LSA_H
#define OSPF6_LSA_H
#include "ospf6_top.h"
+#include "lib/json.h"
/* Debug option */
#define OSPF6_LSA_DEBUG 0x01
@@ -141,9 +142,10 @@ struct ospf6_lsa_handler {
uint16_t lh_type; /* host byte order */
const char *lh_name;
const char *lh_short_name;
- int (*lh_show)(struct vty *, struct ospf6_lsa *);
- char *(*lh_get_prefix_str)(struct ospf6_lsa *, char *buf,
- int buflen, int pos);
+ int (*lh_show)(struct vty *, struct ospf6_lsa *, json_object *json_obj,
+ bool use_json);
+ char *(*lh_get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen,
+ int pos);
uint8_t lh_debug;
};
@@ -206,10 +208,14 @@ extern char *ospf6_lsa_printbuf(struct ospf6_lsa *lsa, char *buf, int size);
extern void ospf6_lsa_header_print_raw(struct ospf6_lsa_header *header);
extern void ospf6_lsa_header_print(struct ospf6_lsa *lsa);
extern void ospf6_lsa_show_summary_header(struct vty *vty);
-extern void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa);
-extern void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa);
-extern void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa);
-extern void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa);
+extern void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json);
+extern void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json);
+extern void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json);
+extern void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json);
extern struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header);
extern struct ospf6_lsa *
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index c136c558cb..9636e1a230 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -346,55 +346,6 @@ int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb)
return (reschedule);
}
-void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level,
- uint16_t *type, uint32_t *id, uint32_t *adv_router,
- struct ospf6_lsdb *lsdb)
-{
- struct ospf6_lsa *lsa;
- const struct route_node *end = NULL;
- void (*showfunc)(struct vty *, struct ospf6_lsa *) = NULL;
-
- switch (level) {
- case OSPF6_LSDB_SHOW_LEVEL_DETAIL:
- showfunc = ospf6_lsa_show;
- break;
- case OSPF6_LSDB_SHOW_LEVEL_INTERNAL:
- showfunc = ospf6_lsa_show_internal;
- break;
- case OSPF6_LSDB_SHOW_LEVEL_DUMP:
- showfunc = ospf6_lsa_show_dump;
- break;
- case OSPF6_LSDB_SHOW_LEVEL_NORMAL:
- default:
- showfunc = ospf6_lsa_show_summary;
- }
-
- if (type && id && adv_router) {
- lsa = ospf6_lsdb_lookup(*type, *id, *adv_router, lsdb);
- if (lsa) {
- if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
- ospf6_lsa_show(vty, lsa);
- else
- (*showfunc)(vty, lsa);
- }
- return;
- }
-
- if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
- ospf6_lsa_show_summary_header(vty);
-
- end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
- type ? *type : 0, adv_router ? *adv_router : 0,
- &lsa);
- while (lsa) {
- if ((!adv_router || lsa->header->adv_router == *adv_router)
- && (!id || lsa->header->id == *id))
- (*showfunc)(vty, lsa);
-
- lsa = ospf6_lsdb_next(end, lsa);
- }
-}
-
uint32_t ospf6_new_ls_id(uint16_t type, uint32_t adv_router,
struct ospf6_lsdb *lsdb)
{
diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h
index 457e3dc4e4..7a62c46b02 100644
--- a/ospf6d/ospf6_lsdb.h
+++ b/ospf6d/ospf6_lsdb.h
@@ -92,7 +92,8 @@ enum ospf_lsdb_show_level {
extern void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level,
uint16_t *type, uint32_t *id, uint32_t *adv_router,
- struct ospf6_lsdb *lsdb);
+ struct ospf6_lsdb *lsdb, json_object *json,
+ bool use_json);
extern uint32_t ospf6_new_ls_id(uint16_t type, uint32_t adv_router,
struct ospf6_lsdb *lsdb);
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_spf.c b/ospf6d/ospf6_spf.c
index 70771c6060..f94252991c 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -432,9 +432,8 @@ void ospf6_spf_table_finish(struct ospf6_route_table *result_table)
}
}
-static const char *const ospf6_spf_reason_str[] = {
- "R+", "R-", "N+", "N-", "L+", "L-", "R*", "N*",
-};
+static const char *const ospf6_spf_reason_str[] = {"R+", "R-", "N+", "N-", "L+",
+ "L-", "R*", "N*", "C"};
void ospf6_spf_reason_string(unsigned int reason, char *buf, int size)
{
@@ -655,7 +654,7 @@ static int ospf6_spf_calculation_thread(struct thread *t)
(long long)runtime.tv_usec);
zlog_info(
- "SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, Reason: %s\n",
+ "SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, Reason: %s",
areas_processed, (long long)runtime.tv_sec,
(long long)runtime.tv_usec, rbuf);
diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h
index 853ce4de07..253888d8ce 100644
--- a/ospf6d/ospf6_spf.h
+++ b/ospf6d/ospf6_spf.h
@@ -88,6 +88,7 @@ struct ospf6_vertex {
#define OSPF6_SPF_FLAGS_LINK_LSA_REMOVED (1 << 5)
#define OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED (1 << 6)
#define OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED (1 << 7)
+#define OSPF6_SPF_FLAGS_CONFIG_CHANGE (1 << 8)
static inline void ospf6_set_spf_reason(struct ospf6 *ospf, unsigned int reason)
{
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 7b4ed84d53..3f72ec828e 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)
@@ -267,6 +268,8 @@ static struct ospf6 *ospf6_create(const char *name)
o->distance_table = route_table_init();
o->fd = -1;
+ o->max_multipath = MULTIPATH_NUM;
+
QOBJ_REG(o, ospf6);
/* Make ospf protocol socket. */
@@ -718,39 +721,6 @@ DEFUN (no_ospf6_distance_ospf6,
return CMD_SUCCESS;
}
-#if 0
-DEFUN (ospf6_distance_source,
- ospf6_distance_source_cmd,
- "distance (1-255) X:X::X:X/M [WORD]",
- "Administrative distance\n"
- "Distance value\n"
- "IP source prefix\n"
- "Access list name\n")
-{
- VTY_DECLVAR_CONTEXT(ospf6, o);
- char *alname = (argc == 4) ? argv[3]->arg : NULL;
- ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ospf6_distance_source,
- no_ospf6_distance_source_cmd,
- "no distance (1-255) X:X::X:X/M [WORD]",
- NO_STR
- "Administrative distance\n"
- "Distance value\n"
- "IP source prefix\n"
- "Access list name\n")
-{
- VTY_DECLVAR_CONTEXT(ospf6, o);
- char *alname = (argc == 5) ? argv[4]->arg : NULL;
- ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname);
-
- return CMD_SUCCESS;
-}
-#endif
-
DEFUN (ospf6_interface_area,
ospf6_interface_area_cmd,
"interface IFNAME area <A.B.C.D|(0-4294967295)>",
@@ -911,54 +881,61 @@ DEFUN (no_ospf6_stub_router_admin,
return CMD_SUCCESS;
}
-#if 0
-DEFUN (ospf6_stub_router_startup,
- ospf6_stub_router_startup_cmd,
- "stub-router on-startup (5-86400)",
- "Make router a stub router\n"
- "Advertise inability to be a transit router\n"
- "Automatically advertise as stub-router on startup of OSPF6\n"
- "Time (seconds) to advertise self as stub-router\n")
+/* Restart OSPF SPF algorithm*/
+static void ospf6_restart_spf(struct ospf6 *ospf6)
{
- return CMD_SUCCESS;
+ ospf6_route_remove_all(ospf6->route_table);
+ ospf6_route_remove_all(ospf6->brouter_table);
+ ospf6_route_remove_all(ospf6->external_table);
+
+ /* Trigger SPF */
+ ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
}
-DEFUN (no_ospf6_stub_router_startup,
- no_ospf6_stub_router_startup_cmd,
- "no stub-router on-startup",
- NO_STR
- "Make router a stub router\n"
- "Advertise inability to be a transit router\n"
- "Automatically advertise as stub-router on startup of OSPF6\n"
- "Time (seconds) to advertise self as stub-router\n")
+/* Set the max paths */
+static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
{
- return CMD_SUCCESS;
+ if (ospf6->max_multipath == paths)
+ return;
+
+ ospf6->max_multipath = paths;
+
+ /* Send deletion to zebra to delete all
+ * ospf specific routes and reinitiate
+ * SPF to reflect the new max multipath.
+ */
+ ospf6_restart_spf(ospf6);
}
-DEFUN (ospf6_stub_router_shutdown,
- ospf6_stub_router_shutdown_cmd,
- "stub-router on-shutdown (5-86400)",
- "Make router a stub router\n"
- "Advertise inability to be a transit router\n"
- "Automatically advertise as stub-router before shutdown\n"
- "Time (seconds) to advertise self as stub-router\n")
+/* Ospf Maximum-paths config support */
+DEFUN(ospf6_max_multipath,
+ ospf6_max_multipath_cmd,
+ "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
+ "Max no of multiple paths for ECMP support\n"
+ "Number of paths\n")
{
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+ int idx_number = 1;
+ int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
+
+ ospf6_maxpath_set(ospf6, maximum_paths);
+
+ return CMD_SUCCESS;
}
-DEFUN (no_ospf6_stub_router_shutdown,
- no_ospf6_stub_router_shutdown_cmd,
- "no stub-router on-shutdown",
- NO_STR
- "Make router a stub router\n"
- "Advertise inability to be a transit router\n"
- "Automatically advertise as stub-router before shutdown\n"
- "Time (seconds) to advertise self as stub-router\n")
+DEFUN(no_ospf6_max_multipath,
+ no_ospf6_max_multipath_cmd,
+ "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
+ NO_STR
+ "Max no of multiple paths for ECMP support\n"
+ "Number of paths\n")
{
- return CMD_SUCCESS;
-}
-#endif
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+ ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
+
+ return CMD_SUCCESS;
+}
static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
bool use_json)
@@ -998,6 +975,7 @@ static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
json_object_int_add(json, "holdTimeMultiplier",
o->spf_hold_multiplier);
+ json_object_int_add(json, "maximumPaths", o->max_multipath);
if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
timersub(&now, &o->ts_spf, &result);
@@ -1080,6 +1058,7 @@ static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
vty_out(vty, " LSA minimum arrival %d msecs\n",
o->lsa_minarrival);
+ vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
/* Show SPF parameters */
vty_out(vty,
@@ -1165,7 +1144,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 +1156,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 +1201,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 +1226,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;
}
@@ -1333,6 +1317,11 @@ static int config_write_ospf6(struct vty *vty)
vty_out(vty, " timers lsa min-arrival %d\n",
ospf6->lsa_minarrival);
+ /* ECMP max path config */
+ if (ospf6->max_multipath != MULTIPATH_NUM)
+ vty_out(vty, " maximum-paths %d\n",
+ ospf6->max_multipath);
+
ospf6_stub_router_config_write(vty, ospf6);
ospf6_redistribute_config_write(vty, ospf6);
ospf6_area_config_write(vty, ospf6);
@@ -1390,20 +1379,13 @@ void ospf6_top_init(void)
install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
-/* For a later time */
-#if 0
- install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
- install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
- install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
- install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
-#endif
+
+ /* maximum-paths command */
+ install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
+ install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
install_element(OSPF6_NODE, &ospf6_distance_cmd);
install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
-#if 0
- install_element (OSPF6_NODE, &ospf6_distance_source_cmd);
- install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd);
-#endif
}
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index 93e25d7599..75dff86cd7 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -127,6 +127,11 @@ struct ospf6 {
* update to neighbors immediatly */
uint8_t inst_shutdown;
+ /* Max number of multiple paths
+ * to support ECMP.
+ */
+ uint16_t max_multipath;
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(ospf6)
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 7a8027a37f..2b7072d34f 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -343,7 +343,14 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
api.safi = SAFI_UNICAST;
api.prefix = *dest;
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
- api.nexthop_num = MIN(nhcount, MULTIPATH_NUM);
+
+ if (nhcount > ospf6->max_multipath) {
+ if (IS_OSPF6_DEBUG_ZEBRA(SEND))
+ zlog_debug(
+ " Nexthop count is greater than configured maximum-path, hence ignore the extra nexthops");
+ }
+ api.nexthop_num = MIN(nhcount, ospf6->max_multipath);
+
ospf6_route_zebra_copy_nexthops(request, api.nexthops, api.nexthop_num,
api.vrf_id);
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c
index 4b958e550f..8d9c85fd08 100644
--- a/ospf6d/ospf6d.c
+++ b/ospf6d/ospf6d.c
@@ -44,6 +44,7 @@
#include "ospf6_flood.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
+#include "lib/json.h"
struct route_node *route_prev(struct route_node *node)
{
@@ -154,53 +155,264 @@ static uint16_t parse_type_spec(int idx_lsa, int argc, struct cmd_token **argv)
return type;
}
+void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level,
+ uint16_t *type, uint32_t *id, uint32_t *adv_router,
+ struct ospf6_lsdb *lsdb, json_object *json_obj,
+ bool use_json)
+{
+ struct ospf6_lsa *lsa;
+ const struct route_node *end = NULL;
+ void (*showfunc)(struct vty *, struct ospf6_lsa *, json_object *,
+ bool) = NULL;
+ json_object *json_array = NULL;
+
+ switch (level) {
+ case OSPF6_LSDB_SHOW_LEVEL_DETAIL:
+ showfunc = ospf6_lsa_show;
+ break;
+ case OSPF6_LSDB_SHOW_LEVEL_INTERNAL:
+ showfunc = ospf6_lsa_show_internal;
+ break;
+ case OSPF6_LSDB_SHOW_LEVEL_DUMP:
+ showfunc = ospf6_lsa_show_dump;
+ break;
+ case OSPF6_LSDB_SHOW_LEVEL_NORMAL:
+ default:
+ showfunc = ospf6_lsa_show_summary;
+ }
+
+ if (use_json)
+ json_array = json_object_new_array();
+
+ if (type && id && adv_router) {
+ lsa = ospf6_lsdb_lookup(*type, *id, *adv_router, lsdb);
+ if (lsa) {
+ if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
+ ospf6_lsa_show(vty, lsa, json_array, use_json);
+ else
+ (*showfunc)(vty, lsa, json_array, use_json);
+ }
+
+ if (use_json)
+ json_object_object_add(json_obj, "lsa", json_array);
+ return;
+ }
+
+ if ((level == OSPF6_LSDB_SHOW_LEVEL_NORMAL) && !use_json)
+ ospf6_lsa_show_summary_header(vty);
+
+ end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
+ type ? *type : 0, adv_router ? *adv_router : 0,
+ &lsa);
+ while (lsa) {
+ if ((!adv_router || lsa->header->adv_router == *adv_router)
+ && (!id || lsa->header->id == *id))
+ (*showfunc)(vty, lsa, json_array, use_json);
+ lsa = ospf6_lsdb_next(end, lsa);
+ }
+
+ if (use_json)
+ json_object_object_add(json_obj, "lsa", json_array);
+}
+
+static void ospf6_lsdb_show_wrapper(struct vty *vty,
+ enum ospf_lsdb_show_level level,
+ uint16_t *type, uint32_t *id,
+ uint32_t *adv_router, bool uj,
+ struct ospf6 *ospf6)
+{
+ struct listnode *i, *j;
+ struct ospf6 *o = ospf6;
+ struct ospf6_area *oa;
+ struct ospf6_interface *oi;
+ json_object *json = NULL;
+ json_object *json_array = NULL;
+ json_object *json_obj = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_array = json_object_new_array();
+ }
+ for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+ if (uj) {
+ json_obj = json_object_new_object();
+ json_object_string_add(json_obj, "areaId", oa->name);
+ } else
+ vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
+ ospf6_lsdb_show(vty, level, type, id, adv_router, oa->lsdb,
+ json_obj, uj);
+ if (uj)
+ json_object_array_add(json_array, json_obj);
+ }
+ if (uj)
+ json_object_object_add(json, "areaScopedLinkStateDb",
+ json_array);
+
+ if (uj)
+ json_array = json_object_new_array();
+ for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
+ if (uj) {
+ json_obj = json_object_new_object();
+ json_object_string_add(json_obj, "areaId",
+ oa->name);
+ json_object_string_add(json_obj, "interface",
+ oi->interface->name);
+ } else
+ vty_out(vty, IF_LSDB_TITLE_FORMAT,
+ oi->interface->name, oa->name);
+ ospf6_lsdb_show(vty, level, type, id, adv_router,
+ oi->lsdb, json_obj, uj);
+ if (uj)
+ json_object_array_add(json_array, json_obj);
+ }
+ }
+ if (uj)
+ json_object_object_add(json, "interfaceScopedLinkStateDb",
+ json_array);
+ if (uj) {
+ json_array = json_object_new_array();
+ json_obj = json_object_new_object();
+ } else
+ vty_out(vty, AS_LSDB_TITLE_FORMAT);
+
+ ospf6_lsdb_show(vty, level, type, id, adv_router, o->lsdb, json_obj,
+ uj);
+
+ if (uj) {
+ json_object_array_add(json_array, json_obj);
+ json_object_object_add(json, "asScopedLinkStateDb", json_array);
+
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else
+ vty_out(vty, "\n");
+}
+
+static void ospf6_lsdb_type_show_wrapper(struct vty *vty,
+ enum ospf_lsdb_show_level level,
+ uint16_t *type, uint32_t *id,
+ uint32_t *adv_router, bool uj,
+ struct ospf6 *ospf6)
+{
+ struct listnode *i, *j;
+ struct ospf6 *o = ospf6;
+ struct ospf6_area *oa;
+ struct ospf6_interface *oi;
+ json_object *json = NULL;
+ json_object *json_array = NULL;
+ json_object *json_obj = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_array = json_object_new_array();
+ }
+
+ switch (OSPF6_LSA_SCOPE(*type)) {
+ case OSPF6_SCOPE_AREA:
+ for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+ if (uj) {
+ json_obj = json_object_new_object();
+ json_object_string_add(json_obj, "areaId",
+ oa->name);
+ } else
+ vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
+
+ ospf6_lsdb_show(vty, level, type, id, adv_router,
+ oa->lsdb, json_obj, uj);
+ if (uj)
+ json_object_array_add(json_array, json_obj);
+ }
+ if (uj)
+ json_object_object_add(json, "areaScopedLinkStateDb",
+ json_array);
+ break;
+
+ case OSPF6_SCOPE_LINKLOCAL:
+ for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
+ if (uj) {
+ json_obj = json_object_new_object();
+ json_object_string_add(
+ json_obj, "areaId", oa->name);
+ json_object_string_add(
+ json_obj, "interface",
+ oi->interface->name);
+ } else
+ vty_out(vty, IF_LSDB_TITLE_FORMAT,
+ oi->interface->name, oa->name);
+
+ ospf6_lsdb_show(vty, level, type, id,
+ adv_router, oi->lsdb, json_obj,
+ uj);
+
+ if (uj)
+ json_object_array_add(json_array,
+ json_obj);
+ }
+ }
+ if (uj)
+ json_object_object_add(
+ json, "interfaceScopedLinkStateDb", json_array);
+ break;
+
+ case OSPF6_SCOPE_AS:
+ if (uj)
+ json_obj = json_object_new_object();
+ else
+ vty_out(vty, AS_LSDB_TITLE_FORMAT);
+
+ ospf6_lsdb_show(vty, level, type, id, adv_router, o->lsdb,
+ json_obj, uj);
+ if (uj) {
+ json_object_array_add(json_array, json_obj);
+ json_object_object_add(json, "asScopedLinkStateDb",
+ json_array);
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else
+ vty_out(vty, "\n");
+}
+
DEFUN (show_ipv6_ospf6_database,
show_ipv6_ospf6_database_cmd,
- "show ipv6 ospf6 database [<detail|dump|internal>]",
+ "show ipv6 ospf6 database [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
"Display Link state database\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_level = 4;
int level;
- struct listnode *i, *j;
+ bool uj = use_json(argc, argv);
struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
-
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
level = parse_show_level(idx_level, argc, argv);
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, NULL, NULL, ospf6->lsdb);
-
- vty_out(vty, "\n");
+ ospf6_lsdb_show_wrapper(vty, level, NULL, NULL, NULL, uj, ospf6);
return CMD_SUCCESS;
}
-DEFUN (show_ipv6_ospf6_database_type,
- show_ipv6_ospf6_database_type_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [<detail|dump|internal>]",
+DEFUN (show_ipv6_ospf6_database_type, show_ipv6_ospf6_database_type_cmd,
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -217,16 +429,14 @@ DEFUN (show_ipv6_ospf6_database_type,
"Display details of LSAs\n"
"Dump LSAs\n"
"Display LSA's internal information\n"
- )
+ JSON_STR)
{
int idx_lsa = 4;
int idx_level = 5;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -235,43 +445,13 @@ DEFUN (show_ipv6_ospf6_database_type,
type = parse_type_spec(idx_lsa, argc, argv);
level = parse_show_level(idx_level, argc, argv);
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL, NULL,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL, NULL,
- oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, NULL, NULL, ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, NULL, NULL, uj, ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_id,
show_ipv6_ospf6_database_id_cmd,
- "show ipv6 ospf6 database <*|linkstate-id> A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <*|linkstate-id> A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -281,16 +461,15 @@ DEFUN (show_ipv6_ospf6_database_id,
"Specify Link state ID as IPv4 address notation\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_ipv4 = 5;
int idx_level = 6;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint32_t id = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -300,30 +479,14 @@ DEFUN (show_ipv6_ospf6_database_id,
inet_pton(AF_INET, argv[idx_ipv4]->arg, &id);
level = parse_show_level(idx_level, argc, argv);
+ ospf6_lsdb_show_wrapper(vty, level, NULL, &id, NULL, uj, ospf6);
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, NULL, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, NULL, oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, &id, NULL, ospf6->lsdb);
-
- vty_out(vty, "\n");
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_router,
show_ipv6_ospf6_database_router_cmd,
- "show ipv6 ospf6 database <*|adv-router> * A.B.C.D <detail|dump|internal>",
+ "show ipv6 ospf6 database <*|adv-router> * A.B.C.D <detail|dump|internal> [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -334,16 +497,15 @@ DEFUN (show_ipv6_ospf6_database_router,
"Specify Advertising Router as IPv4 address notation\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_ipv4 = 6;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -351,24 +513,7 @@ DEFUN (show_ipv6_ospf6_database_router,
inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
level = parse_show_level(idx_level, argc, argv);
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router,
- oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb);
-
- vty_out(vty, "\n");
+ ospf6_lsdb_show_wrapper(vty, level, NULL, NULL, &adv_router, uj, ospf6);
return CMD_SUCCESS;
}
@@ -408,7 +553,7 @@ DEFUN_HIDDEN (show_ipv6_ospf6_database_aggr_router,
return CMD_SUCCESS;
}
ospf6_lsdb_show(vty, level, &type, NULL, NULL,
- oa->temp_router_lsa_lsdb);
+ oa->temp_router_lsa_lsdb, NULL, false);
/* Remove the temp cache */
ospf6_remove_temp_router_lsa(oa);
}
@@ -420,7 +565,7 @@ DEFUN_HIDDEN (show_ipv6_ospf6_database_aggr_router,
DEFUN (show_ipv6_ospf6_database_type_id,
show_ipv6_ospf6_database_type_id_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> linkstate-id A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> linkstate-id A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -439,18 +584,16 @@ DEFUN (show_ipv6_ospf6_database_type_id,
"Display details of LSAs\n"
"Dump LSAs\n"
"Display LSA's internal information\n"
- )
+ JSON_STR)
{
int idx_lsa = 4;
int idx_ipv4 = 6;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t id = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -460,42 +603,13 @@ DEFUN (show_ipv6_ospf6_database_type_id,
inet_pton(AF_INET, argv[idx_ipv4]->arg, &id);
level = parse_show_level(idx_level, argc, argv);
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, NULL, oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, NULL,
- oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, &id, NULL, ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, &id, NULL, uj, ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_router,
show_ipv6_ospf6_database_type_router_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> <*|adv-router> A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> <*|adv-router> A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -515,18 +629,16 @@ DEFUN (show_ipv6_ospf6_database_type_router,
"Display details of LSAs\n"
"Dump LSAs\n"
"Display LSA's internal information\n"
- )
+ JSON_STR)
{
int idx_lsa = 4;
int idx_ipv4 = 6;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -535,45 +647,15 @@ DEFUN (show_ipv6_ospf6_database_type_router,
inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
level = parse_show_level(idx_level, argc, argv);
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, NULL, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_id_router,
show_ipv6_ospf6_database_id_router_cmd,
- "show ipv6 ospf6 database * A.B.C.D A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database * A.B.C.D A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -584,18 +666,16 @@ DEFUN (show_ipv6_ospf6_database_id_router,
"Display details of LSAs\n"
"Dump LSAs\n"
"Display LSA's internal information\n"
- )
+ JSON_STR)
{
int idx_ls_id = 5;
int idx_adv_rtr = 6;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint32_t id = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
@@ -603,31 +683,14 @@ DEFUN (show_ipv6_ospf6_database_id_router,
inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
level = parse_show_level(idx_level, argc, argv);
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router,
- oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb);
-
- vty_out(vty, "\n");
+ ospf6_lsdb_show_wrapper(vty, level, NULL, &id, &adv_router, uj, ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
show_ipv6_ospf6_database_adv_router_linkstate_id_cmd,
- "show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database adv-router A.B.C.D linkstate-id A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -638,18 +701,17 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
"Specify Link state ID as IPv4 address notation\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_adv_rtr = 5;
int idx_ls_id = 7;
int idx_level = 8;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint32_t id = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -658,30 +720,13 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
level = parse_show_level(idx_level, argc, argv);
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router,
- oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb);
-
- vty_out(vty, "\n");
+ ospf6_lsdb_show_wrapper(vty, level, NULL, &id, &adv_router, uj, ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_id_router,
show_ipv6_ospf6_database_type_id_router_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D A.B.C.D [<dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D A.B.C.D [<dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -698,20 +743,19 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
"Specify Link state ID as IPv4 address notation\n"
"Specify Advertising Router as IPv4 address notation\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_lsa = 4;
int idx_ls_id = 5;
int idx_adv_rtr = 6;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t id = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -722,45 +766,15 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
level = parse_show_level(idx_level, argc, argv);
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, &id, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
show_ipv6_ospf6_database_type_adv_router_linkstate_id_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> adv-router A.B.C.D linkstate-id A.B.C.D [<dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> adv-router A.B.C.D linkstate-id A.B.C.D [<dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -779,20 +793,19 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
"Search by Link state ID\n"
"Specify Link state ID as IPv4 address notation\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_lsa = 4;
int idx_adv_rtr = 6;
int idx_ls_id = 8;
int idx_level = 9;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t id = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
@@ -803,44 +816,14 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
level = parse_show_level(idx_level, argc, argv);
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, &id, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_self_originated,
show_ipv6_ospf6_database_self_originated_cmd,
- "show ipv6 ospf6 database self-originated [<detail|dump|internal>]",
+ "show ipv6 ospf6 database self-originated [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -848,46 +831,28 @@ DEFUN (show_ipv6_ospf6_database_self_originated,
"Display Self-originated LSAs\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_level = 5;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
level = parse_show_level(idx_level, argc, argv);
adv_router = ospf6->router_id;
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
- oa->name);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router,
- oi->lsdb);
- }
- }
-
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb);
-
- vty_out(vty, "\n");
+ ospf6_lsdb_show_wrapper(vty, level, NULL, NULL, &adv_router, uj, ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_self_originated,
show_ipv6_ospf6_database_type_self_originated_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -904,17 +869,16 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
"Display Self-originated LSAs\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_lsa = 4;
int idx_level = 6;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t adv_router = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
@@ -923,44 +887,14 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
adv_router = ospf6->router_id;
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, NULL,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, NULL, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated linkstate-id A.B.C.D [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> self-originated linkstate-id A.B.C.D [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -979,19 +913,18 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
"Specify Link state ID as IPv4 address notation\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_lsa = 4;
int idx_ls_id = 7;
int idx_level = 8;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t adv_router = 0;
uint32_t id = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
@@ -1000,44 +933,14 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
level = parse_show_level(idx_level, argc, argv);
adv_router = ospf6->router_id;
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, &id, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
show_ipv6_ospf6_database_type_id_self_originated_cmd,
- "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D self-originated [<detail|dump|internal>]",
+ "show ipv6 ospf6 database <router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix> A.B.C.D self-originated [<detail|dump|internal>] [json]",
SHOW_STR
IPV6_STR
OSPF6_STR
@@ -1055,19 +958,18 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
"Display Self-originated LSAs\n"
"Display details of LSAs\n"
"Dump LSAs\n"
- "Display LSA's internal information\n")
+ "Display LSA's internal information\n"
+ JSON_STR)
{
int idx_lsa = 4;
int idx_ls_id = 5;
int idx_level = 7;
int level;
- struct listnode *i, *j;
- struct ospf6 *ospf6;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
uint16_t type = 0;
uint32_t adv_router = 0;
uint32_t id = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6;
ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
OSPF6_CMD_CHECK_RUNNING(ospf6);
@@ -1076,38 +978,8 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
level = parse_show_level(idx_level, argc, argv);
adv_router = ospf6->router_id;
- switch (OSPF6_LSA_SCOPE(type)) {
- case OSPF6_SCOPE_AREA:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- oa->lsdb);
- }
- break;
-
- case OSPF6_SCOPE_LINKLOCAL:
- for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
- vty_out(vty, IF_LSDB_TITLE_FORMAT,
- oi->interface->name, oa->name);
- ospf6_lsdb_show(vty, level, &type, &id,
- &adv_router, oi->lsdb);
- }
- }
- break;
-
- case OSPF6_SCOPE_AS:
- vty_out(vty, AS_LSDB_TITLE_FORMAT);
- ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
- ospf6->lsdb);
- break;
-
- default:
- assert(0);
- break;
- }
-
- vty_out(vty, "\n");
+ ospf6_lsdb_type_show_wrapper(vty, level, &type, &id, &adv_router, uj,
+ ospf6);
return CMD_SUCCESS;
}
@@ -1134,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);
@@ -1147,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 {