summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Hopps <chopps@labn.net>2024-02-13 11:37:29 +0100
committerGitHub <noreply@github.com>2024-02-13 11:37:29 +0100
commit7b94a923ae7a8e6bf1a5fb79f6804f311134d389 (patch)
treeff34b8fe41ee12cfe0c52a40e0a56a36ab8415a0
parentMerge pull request #15361 from idryzhov/fix-be-interested (diff)
parenttests: adapt ospfapiclient test to new json output (diff)
downloadfrr-7b94a923ae7a8e6bf1a5fb79f6804f311134d389.tar.xz
frr-7b94a923ae7a8e6bf1a5fb79f6804f311134d389.zip
Merge pull request #15042 from Orange-OpenSource/ospf-te
ospfd: Add Opaque LSA decoder for json output
-rw-r--r--ospfd/ospf_ext.c231
-rw-r--r--ospfd/ospf_opaque.c17
-rw-r--r--ospfd/ospf_ri.c301
-rw-r--r--ospfd/ospf_te.c475
-rw-r--r--tests/topotests/ospfapi/test_ospf_clientapi.py64
5 files changed, 772 insertions, 316 deletions
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c
index d82c2146c..df0b3b908 100644
--- a/ospfd/ospf_ext.c
+++ b/ospfd/ospf_ext.c
@@ -31,6 +31,7 @@
#include "network.h"
#include "if.h"
#include "libospf.h" /* for ospf interface types */
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -1715,23 +1716,29 @@ static void ospf_ext_lsa_schedule(struct ext_itf *exti, enum lsa_opcode op)
/* Cisco experimental SubTLV */
static uint16_t show_vty_ext_link_rmt_itf_addr(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_rmt_itf_addr *top =
(struct ext_subtlv_rmt_itf_addr *)tlvh;
check_tlv_size(EXT_SUBTLV_RMT_ITF_ADDR_SIZE, "Remote Itf. Address");
- vty_out(vty,
- " Remote Interface Address Sub-TLV: Length %u\n Address: %pI4\n",
- ntohs(top->header.length), &top->value);
+ if (!json)
+ vty_out(vty,
+ " Remote Interface Address Sub-TLV: Length %u\n Address: %pI4\n",
+ ntohs(top->header.length), &top->value);
+ else
+ json_object_string_addf(json, "remoteInterfaceAddress", "%pI4",
+ &top->value);
return TLV_SIZE(tlvh);
}
/* Adjacency SID SubTLV */
static uint16_t show_vty_ext_link_adj_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_adj_sid *top = (struct ext_subtlv_adj_sid *)tlvh;
uint8_t tlv_size;
@@ -1741,21 +1748,35 @@ static uint16_t show_vty_ext_link_adj_sid(struct vty *vty,
: SID_INDEX_SIZE(EXT_SUBTLV_ADJ_SID_SIZE);
check_tlv_size(tlv_size, "Adjacency SID");
- vty_out(vty,
- " Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\t%s: %u\n",
- ntohs(top->header.length), top->flags, top->mtid, top->weight,
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
+ if (!json)
+ vty_out(vty,
+ " Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\t%s: %u\n",
+ ntohs(top->header.length), top->flags, top->mtid,
+ top->weight,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ json_object_string_addf(json, "weight", "0x%x", top->weight);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
/* LAN Adjacency SubTLV */
static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_lan_adj_sid *top =
(struct ext_subtlv_lan_adj_sid *)tlvh;
@@ -1766,42 +1787,67 @@ static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
: SID_INDEX_SIZE(EXT_SUBTLV_LAN_ADJ_SID_SIZE);
check_tlv_size(tlv_size, "LAN-Adjacency SID");
- vty_out(vty,
- " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n",
- ntohs(top->header.length), top->flags, top->mtid, top->weight,
- &top->neighbor_id,
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
+ if (!json)
+ vty_out(vty,
+ " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n",
+ ntohs(top->header.length), top->flags, top->mtid,
+ top->weight, &top->neighbor_id,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ json_object_string_addf(json, "weight", "0x%x", top->weight);
+ json_object_string_addf(json, "neighborID", "%pI4",
+ &top->neighbor_id);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
vty_out(vty, " TLV size %d exceeds buffer size. Abort!",
TLV_SIZE(tlvh));
return buf_size;
}
-
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
return TLV_SIZE(tlvh);
}
/* Extended Link Sub TLVs */
static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct ext_tlv_link *top = (struct ext_tlv_link *)ext;
struct tlv_header *tlvh;
uint16_t length = ntohs(top->header.length);
uint16_t sum = 0;
+ json_object *jadj = NULL, *obj = NULL;
/* Verify that TLV length is valid against remaining buffer size */
if (length > buf_size) {
@@ -1811,12 +1857,22 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
return buf_size;
}
- vty_out(vty,
- " Extended Link TLV: Length %u\n Link Type: 0x%x\n"
- " Link ID: %pI4\n",
- ntohs(top->header.length), top->link_type,
- &top->link_id);
- vty_out(vty, " Link data: %pI4\n", &top->link_data);
+ if (!json) {
+ vty_out(vty,
+ " Extended Link TLV: Length %u\n Link Type: 0x%x\n"
+ " Link ID: %pI4\n",
+ ntohs(top->header.length), top->link_type,
+ &top->link_id);
+ vty_out(vty, " Link data: %pI4\n", &top->link_data);
+ } else {
+ json_object_string_addf(json, "linkType", "0x%x",
+ top->link_type);
+ json_object_string_addf(json, "linkID", "%pI4", &top->link_id);
+ json_object_string_addf(json, "linkData", "%pI4",
+ &top->link_data);
+ jadj = json_object_new_array();
+ json_object_object_add(json, "adjacencySID", jadj);
+ }
/* Skip Extended TLV and parse sub-TLVs */
length -= EXT_TLV_LINK_SIZE;
@@ -1825,16 +1881,27 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
for (; sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_SUBTLV_ADJ_SID:
- sum += show_vty_ext_link_adj_sid(vty, tlvh);
+ if (json) {
+ obj = json_object_new_object();
+ json_object_array_add(jadj, obj);
+ } else
+ obj = NULL;
+ sum += show_vty_ext_link_adj_sid(vty, tlvh, obj);
break;
case EXT_SUBTLV_LAN_ADJ_SID:
- sum += show_vty_ext_link_lan_adj_sid(vty, tlvh);
+ if (json) {
+ obj = json_object_new_object();
+ json_object_array_add(jadj, obj);
+ } else
+ obj = NULL;
+ sum += show_vty_ext_link_lan_adj_sid(vty, tlvh, obj);
break;
case EXT_SUBTLV_RMT_ITF_ADDR:
- sum += show_vty_ext_link_rmt_itf_addr(vty, tlvh);
+ sum += show_vty_ext_link_rmt_itf_addr(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1849,9 +1916,12 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jlink = NULL;
- if (json)
- return;
+ if (json) {
+ jlink = json_object_new_object();
+ json_object_object_add(json, "extendedLink", jlink);
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1860,10 +1930,12 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_TLV_LINK:
- sum += show_vty_link_info(vty, tlvh, length - sum);
+ sum += show_vty_link_info(vty, tlvh, length - sum,
+ jlink);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ jlink);
break;
}
}
@@ -1871,7 +1943,8 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
/* Prefix SID SubTLV */
static uint16_t show_vty_ext_pref_pref_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_prefix_sid *top =
(struct ext_subtlv_prefix_sid *)tlvh;
@@ -1882,27 +1955,39 @@ static uint16_t show_vty_ext_pref_pref_sid(struct vty *vty,
: SID_INDEX_SIZE(EXT_SUBTLV_PREFIX_SID_SIZE);
check_tlv_size(tlv_size, "Prefix SID");
- vty_out(vty,
- " Prefix SID Sub-TLV: Length %u\n\tAlgorithm: %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\t%s: %u\n",
- ntohs(top->header.length), top->algorithm, top->flags,
- top->mtid,
- CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
-
+ if (!json)
+ vty_out(vty,
+ " Prefix SID Sub-TLV: Length %u\n\tAlgorithm: %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\t%s: %u\n",
+ ntohs(top->header.length), top->algorithm, top->flags,
+ top->mtid,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_int_add(json, "algorithm", top->algorithm);
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
/* Extended Prefix SubTLVs */
static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct ext_tlv_prefix *top = (struct ext_tlv_prefix *)ext;
struct tlv_header *tlvh;
uint16_t length = ntohs(top->header.length);
uint16_t sum = 0;
+ json_object *jsid = NULL;
/* Verify that TLV length is valid against remaining buffer size */
if (length > buf_size) {
@@ -1912,11 +1997,21 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
return buf_size;
}
- vty_out(vty,
- " Extended Prefix TLV: Length %u\n\tRoute Type: %u\n"
- "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n",
- ntohs(top->header.length), top->route_type, top->af, top->flags,
- &top->address, top->pref_length);
+ if (!json)
+ vty_out(vty,
+ " Extended Prefix TLV: Length %u\n\tRoute Type: %u\n"
+ "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n",
+ ntohs(top->header.length), top->route_type, top->af,
+ top->flags, &top->address, top->pref_length);
+ else {
+ json_object_int_add(json, "routeType", top->route_type);
+ json_object_string_addf(json, "addressFamily", "0x%x", top->af);
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "address", "%pI4", &top->address);
+ json_object_int_add(json, "prefixLength", top->pref_length);
+ jsid = json_object_new_object();
+ json_object_object_add(json, "prefixSID", jsid);
+ }
/* Skip Extended Prefix TLV and parse sub-TLVs */
length -= EXT_TLV_PREFIX_SIZE;
@@ -1925,10 +2020,11 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
for (; sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_SUBTLV_PREFIX_SID:
- sum += show_vty_ext_pref_pref_sid(vty, tlvh);
+ sum += show_vty_ext_pref_pref_sid(vty, tlvh, jsid);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1943,9 +2039,12 @@ static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jpref = NULL;
- if (json)
- return;
+ if (json) {
+ jpref = json_object_new_object();
+ json_object_object_add(json, "extendedPrefix", jpref);
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1954,10 +2053,12 @@ static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_TLV_PREFIX:
- sum += show_vty_pref_info(vty, tlvh, length - sum);
+ sum += show_vty_pref_info(vty, tlvh, length - sum,
+ jpref);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ jpref);
break;
}
}
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 24a850c73..5d2d65658 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -1251,12 +1251,12 @@ void ospf_opaque_config_write_debug(struct vty *vty)
void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
json_object *json)
{
- char buf[128], *bp;
struct lsa_header *lsah = lsa->data;
uint32_t lsid = ntohl(lsah->id.s_addr);
uint8_t opaque_type = GET_OPAQUE_TYPE(lsid);
uint32_t opaque_id = GET_OPAQUE_ID(lsid);
struct ospf_opaque_functab *functab;
+ json_object *jopaque = NULL;
int len, lenValid;
/* Switch output functionality by vty address. */
@@ -1277,17 +1277,14 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
ospf_opaque_type_name(opaque_type));
json_object_int_add(json, "opaqueId", opaque_id);
len = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
- json_object_int_add(json, "opaqueDataLength", len);
+ json_object_int_add(json, "opaqueLength", len);
lenValid = VALID_OPAQUE_INFO_LEN(lsah);
- json_object_boolean_add(json, "opaqueDataLengthValid",
+ json_object_boolean_add(json, "opaqueLengthValid",
lenValid);
if (lenValid) {
- bp = asnprintfrr(MTYPE_TMP, buf, sizeof(buf),
- "%*pHXn", (int)len,
- (lsah + 1));
- json_object_string_add(json, "opaqueData", buf);
- if (bp != buf)
- XFREE(MTYPE_TMP, bp);
+ jopaque = json_object_new_object();
+ json_object_object_add(json, "opaqueValues",
+ jopaque);
}
}
} else {
@@ -1304,7 +1301,7 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
/* Call individual output functions. */
if ((functab = ospf_opaque_functab_lookup(lsa)) != NULL)
if (functab->show_opaque_info != NULL)
- (*functab->show_opaque_info)(vty, json, lsa);
+ (*functab->show_opaque_info)(vty, jopaque, lsa);
return;
}
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 723ccf59a..99326b41b 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -24,6 +24,7 @@
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "mpls.h"
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -1216,15 +1217,20 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
} \
} while (0)
-static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
check_tlv_size(RI_TLV_CAPABILITIES_SIZE, "Router Capabilities");
if (vty != NULL)
- vty_out(vty, " Router Capabilities: 0x%x\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Router Capabilities: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "routerCapabilities",
+ "0x%x", ntohl(top->value));
else
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
@@ -1232,7 +1238,8 @@ static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
}
static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_address *top =
(struct ri_pce_subtlv_address *)tlvh;
@@ -1240,20 +1247,28 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
if (ntohs(top->address.type) == PCE_ADDRESS_IPV4) {
check_tlv_size(PCE_ADDRESS_IPV4_SIZE, "PCE Address");
if (vty != NULL)
- vty_out(vty, " PCE Address: %pI4\n",
- &top->address.value);
+ if (!json)
+ vty_out(vty, " PCE Address: %pI4\n",
+ &top->address.value);
+ else
+ json_object_string_addf(json, "pceAddress",
+ "%pI4",
+ &top->address.value);
else
zlog_debug(" PCE Address: %pI4",
&top->address.value);
} else if (ntohs(top->address.type) == PCE_ADDRESS_IPV6) {
- /* TODO: Add support to IPv6 with inet_ntop() */
check_tlv_size(PCE_ADDRESS_IPV6_SIZE, "PCE Address");
if (vty != NULL)
- vty_out(vty, " PCE Address: 0x%x\n",
- ntohl(top->address.value.s_addr));
+ if (!json)
+ vty_out(vty,
+ " PCE Address: unsupported IPv6\n");
+ else
+ json_object_string_add(json, "pceAddress",
+ "unsupported IPv6");
+
else
- zlog_debug(" PCE Address: 0x%x",
- ntohl(top->address.value.s_addr));
+ zlog_debug(" PCE Address: unsupported IPv6");
} else {
if (vty != NULL)
vty_out(vty, " Wrong PCE Address type: 0x%x\n",
@@ -1267,7 +1282,8 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_path_scope *top =
(struct ri_pce_subtlv_path_scope *)tlvh;
@@ -1275,7 +1291,12 @@ static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
check_tlv_size(RI_PCE_SUBTLV_PATH_SCOPE_SIZE, "PCE Path Scope");
if (vty != NULL)
- vty_out(vty, " PCE Path Scope: 0x%x\n", ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Path Scope: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "pcePathScope", "0x%x",
+ ntohl(top->value));
else
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
@@ -1283,7 +1304,8 @@ static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
struct in_addr tmp;
@@ -1293,13 +1315,21 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = top->value;
if (vty != NULL)
- vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
+ if (!json)
+ vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
+ else
+ json_object_string_addf(json, "pceDomainArea",
+ "%pI4", &tmp);
else
zlog_debug(" PCE Domain Area: %pI4", &tmp);
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
if (vty != NULL)
- vty_out(vty, " PCE Domain AS: %d\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Domain AS: %d\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "pceDomainAS",
+ ntohl(top->value));
else
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
} else {
@@ -1315,7 +1345,8 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_neighbor *top =
@@ -1327,13 +1358,22 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = top->value;
if (vty != NULL)
- vty_out(vty, " PCE Neighbor Area: %pI4\n", &tmp);
+ if (!json)
+ vty_out(vty, " PCE Neighbor Area: %pI4\n",
+ &tmp);
+ else
+ json_object_string_addf(json, "pceNeighborArea",
+ "%pI4", &tmp);
else
zlog_debug(" PCE Neighbor Area: %pI4", &tmp);
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
if (vty != NULL)
- vty_out(vty, " PCE Neighbor AS: %d\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Neighbor AS: %d\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "pceNeighborAS",
+ ntohl(top->value));
else
zlog_debug(" PCE Neighbor AS: %d",
ntohl(top->value));
@@ -1350,7 +1390,8 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_cap_flag *top =
(struct ri_pce_subtlv_cap_flag *)tlvh;
@@ -1358,8 +1399,12 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
check_tlv_size(RI_PCE_SUBTLV_CAP_FLAG_SIZE, "PCE Capabilities");
if (vty != NULL)
- vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "pceCapabilities",
+ "0x%x", ntohl(top->value));
else
zlog_debug(" PCE Capabilities Flag: 0x%x",
ntohl(top->value));
@@ -1368,8 +1413,10 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
if (vty != NULL)
vty_out(vty,
@@ -1383,8 +1430,18 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty,
+ " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
else
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
ntohs(tlvh->type), ntohs(tlvh->length));
@@ -1393,7 +1450,7 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct tlv_header *tlvh;
uint16_t length = ntohs(ri->length);
@@ -1410,22 +1467,23 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
for (tlvh = ri; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_PCE_SUBTLV_ADDRESS:
- sum += show_vty_pce_subtlv_address(vty, tlvh);
+ sum += show_vty_pce_subtlv_address(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_PATH_SCOPE:
- sum += show_vty_pce_subtlv_path_scope(vty, tlvh);
+ sum += show_vty_pce_subtlv_path_scope(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_DOMAIN:
- sum += show_vty_pce_subtlv_domain(vty, tlvh);
+ sum += show_vty_pce_subtlv_domain(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_NEIGHBOR:
- sum += show_vty_pce_subtlv_neighbor(vty, tlvh);
+ sum += show_vty_pce_subtlv_neighbor(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_CAP_FLAG:
- sum += show_vty_pce_subtlv_cap_flag(vty, tlvh);
+ sum += show_vty_pce_subtlv_cap_flag(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1433,33 +1491,62 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
}
/* Display Segment Routing Algorithm TLV information */
-static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_sr_algorithm *algo =
(struct ri_sr_tlv_sr_algorithm *)tlvh;
int i;
+ json_object *json_algo, *obj;
+ char buf[2];
check_tlv_size(ALGORITHM_COUNT, "Segment Routing Algorithm");
- if (vty != NULL) {
- vty_out(vty, " Segment Routing Algorithm TLV:\n");
- for (i = 0; i < ntohs(algo->header.length); i++) {
- switch (algo->value[i]) {
- case 0:
- vty_out(vty, " Algorithm %d: SPF\n", i);
- break;
- case 1:
- vty_out(vty, " Algorithm %d: Strict SPF\n",
- i);
- break;
- default:
- vty_out(vty,
- " Algorithm %d: Unknown value %d\n", i,
- algo->value[i]);
- break;
+ if (vty != NULL)
+ if (!json) {
+ vty_out(vty, " Segment Routing Algorithm TLV:\n");
+ for (i = 0; i < ntohs(algo->header.length); i++) {
+ switch (algo->value[i]) {
+ case 0:
+ vty_out(vty,
+ " Algorithm %d: SPF\n", i);
+ break;
+ case 1:
+ vty_out(vty,
+ " Algorithm %d: Strict SPF\n",
+ i);
+ break;
+ default:
+ vty_out(vty,
+ " Algorithm %d: Unknown value %d\n", i,
+ algo->value[i]);
+ break;
+ }
+ }
+ } else {
+ json_algo = json_object_new_array();
+ json_object_object_add(json, "algorithms",
+ json_algo);
+ for (i = 0; i < ntohs(algo->header.length); i++) {
+ obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ switch (algo->value[i]) {
+ case 0:
+ json_object_string_add(obj, buf, "SPF");
+ break;
+ case 1:
+ json_object_string_add(obj, buf,
+ "strictSPF");
+ break;
+ default:
+ json_object_string_add(obj, buf,
+ "unknown");
+ break;
+ }
+ json_object_array_add(json_algo, obj);
}
}
- } else {
+ else {
zlog_debug(" Segment Routing Algorithm TLV:");
for (i = 0; i < ntohs(algo->header.length); i++)
switch (algo->value[i]) {
@@ -1480,24 +1567,47 @@ static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
}
/* Display Segment Routing SID/Label Range TLV information */
-static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_sid_label_range *range =
(struct ri_sr_tlv_sid_label_range *)tlvh;
+ json_object *obj;
+ uint32_t upper;
check_tlv_size(RI_SR_TLV_LABEL_RANGE_SIZE, "SR Label Range");
- if (vty != NULL) {
- vty_out(vty,
- " Segment Routing %s Range TLV:\n"
- " Range Size = %d\n"
- " SID Label = %d\n\n",
- ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
- ? "Global"
- : "Local",
- GET_RANGE_SIZE(ntohl(range->size)),
- GET_LABEL(ntohl(range->lower.value)));
- } else {
+ if (vty != NULL)
+ if (!json) {
+ vty_out(vty,
+ " Segment Routing %s Range TLV:\n"
+ " Range Size = %d\n"
+ " SID Label = %d\n\n",
+ ntohs(range->header.type) ==
+ RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "Global"
+ : "Local",
+ GET_RANGE_SIZE(ntohl(range->size)),
+ GET_LABEL(ntohl(range->lower.value)));
+ } else {
+ /*
+ * According to draft-ietf-teas-yang-sr-te-topo, SRGB
+ * and SRLB are describe with lower and upper bounds
+ */
+ upper = GET_LABEL(ntohl(range->lower.value)) +
+ GET_RANGE_SIZE(ntohl(range->size)) - 1;
+ obj = json_object_new_object();
+ json_object_int_add(obj, "upperBound", upper);
+ json_object_int_add(obj, "lowerBound",
+ GET_LABEL(ntohl(range->lower.value)));
+ json_object_object_add(json,
+ ntohs(range->header.type) ==
+ RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "srgb"
+ : "srlb",
+ obj);
+ }
+ else {
zlog_debug(
" Segment Routing %s Range TLV: Range Size = %d SID Label = %d",
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
@@ -1511,22 +1621,25 @@ static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
}
/* Display Segment Routing Maximum Stack Depth TLV information */
-static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_node_msd *msd = (struct ri_sr_tlv_node_msd *)tlvh;
check_tlv_size(RI_SR_TLV_NODE_MSD_SIZE, "Node Maximum Stack Depth");
- if (vty != NULL) {
- vty_out(vty,
- " Segment Routing MSD TLV:\n"
- " Node Maximum Stack Depth = %d\n",
- msd->value);
- } else {
+ if (vty != NULL)
+ if (!json)
+ vty_out(vty,
+ " Segment Routing MSD TLV:\n"
+ " Node Maximum Stack Depth = %d\n",
+ msd->value);
+ else
+ json_object_int_add(json, "nodeMsd", msd->value);
+ else
zlog_debug(
" Segment Routing MSD TLV: Node Maximum Stack Depth = %d",
msd->value);
- }
return TLV_SIZE(tlvh);
}
@@ -1538,9 +1651,14 @@ static void ospf_router_info_show_info(struct vty *vty,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jri = NULL, *jpce = NULL, *jsr = NULL;
- if (json)
- return;
+ if (json) {
+ jri = json_object_new_object();
+ json_object_object_add(json, "routerInformation", jri);
+ jpce = json_object_new_object();
+ jsr = json_object_new_object();
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1549,30 +1667,36 @@ static void ospf_router_info_show_info(struct vty *vty,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_TLV_CAPABILITIES:
- sum += show_vty_router_cap(vty, tlvh);
+ sum += show_vty_router_cap(vty, tlvh, jri);
break;
case RI_TLV_PCE:
tlvh++;
sum += TLV_HDR_SIZE;
- sum += show_vty_pce_info(vty, tlvh, length - sum);
+ sum += show_vty_pce_info(vty, tlvh, length - sum, jpce);
break;
case RI_SR_TLV_SR_ALGORITHM:
- sum += show_vty_sr_algorithm(vty, tlvh);
+ sum += show_vty_sr_algorithm(vty, tlvh, jsr);
break;
case RI_SR_TLV_SRGB_LABEL_RANGE:
case RI_SR_TLV_SRLB_LABEL_RANGE:
- sum += show_vty_sr_range(vty, tlvh);
+ sum += show_vty_sr_range(vty, tlvh, jsr);
break;
case RI_SR_TLV_NODE_MSD:
- sum += show_vty_sr_msd(vty, tlvh);
+ sum += show_vty_sr_msd(vty, tlvh, jsr);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length);
+ sum += show_vty_unknown_tlv(vty, tlvh, length, jri);
break;
}
}
+ if (json) {
+ if (json_object_object_length(jpce) > 1)
+ json_object_object_add(jri, "pceInformation", jpce);
+ if (json_object_object_length(jsr) > 1)
+ json_object_object_add(jri, "segmentRouting", jsr);
+ }
return;
}
@@ -2045,7 +2169,7 @@ DEFUN (show_ip_ospf_router_info,
if (OspfRI.enabled) {
vty_out(vty, "--- Router Information parameters ---\n");
- show_vty_router_cap(vty, &OspfRI.router_cap.header);
+ show_vty_router_cap(vty, &OspfRI.router_cap.header, NULL);
} else {
if (vty != NULL)
vty_out(vty,
@@ -2074,27 +2198,32 @@ DEFUN (show_ip_opsf_router_info_pce,
if (pce->pce_address.header.type != 0)
show_vty_pce_subtlv_address(vty,
- &pce->pce_address.header);
+ &pce->pce_address.header,
+ NULL);
if (pce->pce_scope.header.type != 0)
show_vty_pce_subtlv_path_scope(vty,
- &pce->pce_scope.header);
+ &pce->pce_scope.header,
+ NULL);
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
if (domain->header.type != 0)
show_vty_pce_subtlv_domain(vty,
- &domain->header);
+ &domain->header,
+ NULL);
}
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
if (neighbor->header.type != 0)
show_vty_pce_subtlv_neighbor(vty,
- &neighbor->header);
+ &neighbor->header,
+ NULL);
}
if (pce->pce_cap_flag.header.type != 0)
show_vty_pce_subtlv_cap_flag(vty,
- &pce->pce_cap_flag.header);
+ &pce->pce_cap_flag.header,
+ NULL);
} else {
vty_out(vty, " PCE info is disabled on this router\n");
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index d203b5ef4..9ba9a7659 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -31,6 +31,7 @@
#include "link_state.h"
#include "zclient.h"
#include "printfrr.h"
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -3141,14 +3142,19 @@ static void ospf_te_init_ted(struct ls_ted *ted, struct ospf *ospf)
} \
} while (0)
-static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh;
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Router Address");
if (vty != NULL)
- vty_out(vty, " Router-Address: %pI4\n", &top->value);
+ if (!json)
+ vty_out(vty, " Router-Address: %pI4\n", &top->value);
+ else
+ json_object_string_addf(json, "routerAddress", "%pI4",
+ &top->value);
else
zlog_debug(" Router-Address: %pI4", &top->value);
@@ -3156,7 +3162,7 @@ static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
}
static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct te_tlv_link *top = (struct te_tlv_link *)tlvh;
@@ -3173,8 +3179,12 @@ static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Link: %u octets of data\n",
- ntohs(top->header.length));
+ if (!json)
+ vty_out(vty, " Link: %u octets of data\n",
+ ntohs(top->header.length));
+ else
+ json_object_int_add(json, "teLinkDataLength",
+ ntohs(top->header.length));
else
zlog_debug(" Link: %u octets of data",
ntohs(top->header.length));
@@ -3183,7 +3193,8 @@ static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
}
static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_link_type *top;
const char *cp = "Unknown";
@@ -3203,8 +3214,11 @@ static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
}
if (vty != NULL)
- vty_out(vty, " Link-Type: %s (%u)\n", cp,
- top->link_type.value);
+ if (!json)
+ vty_out(vty, " Link-Type: %s (%u)\n", cp,
+ top->link_type.value);
+ else
+ json_object_string_add(json, "accessType", cp);
else
zlog_debug(" Link-Type: %s (%u)", cp, top->link_type.value);
@@ -3212,7 +3226,8 @@ static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_link_id *top;
@@ -3220,7 +3235,11 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
top = (struct te_link_subtlv_link_id *)tlvh;
if (vty != NULL)
- vty_out(vty, " Link-ID: %pI4\n", &top->value);
+ if (!json)
+ vty_out(vty, " Link-ID: %pI4\n", &top->value);
+ else
+ json_object_string_addf(json, "linkID", "%pI4",
+ &top->value);
else
zlog_debug(" Link-ID: %pI4", &top->value);
@@ -3229,9 +3248,12 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size,
+ json_object *json)
{
struct te_link_subtlv_lclif_ipaddr *top;
+ json_object *json_addr, *json_obj;
+ char buf[4];
int i, n;
if (TLV_SIZE(tlvh) > buf_size) {
@@ -3250,13 +3272,29 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
n = ntohs(tlvh->length) / sizeof(top->value[0]);
if (vty != NULL)
- vty_out(vty, " Local Interface IP Address(es): %d\n", n);
+ if (!json)
+ vty_out(vty, " Local Interface IP Address(es): %d\n",
+ n);
+ else {
+ json_addr = json_object_new_array();
+ json_object_object_add(json, "localIPAddresses",
+ json_addr);
+ }
else
zlog_debug(" Local Interface IP Address(es): %d", n);
for (i = 0; i < n; i++) {
if (vty != NULL)
- vty_out(vty, " #%d: %pI4\n", i, &top->value[i]);
+ if (!json)
+ vty_out(vty, " #%d: %pI4\n", i,
+ &top->value[i]);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ json_object_string_addf(json_obj, buf, "%pI4",
+ &top->value[i]);
+ json_object_array_add(json_addr, json_obj);
+ }
else
zlog_debug(" #%d: %pI4", i, &top->value[i]);
}
@@ -3265,9 +3303,12 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size,
+ json_object *json)
{
struct te_link_subtlv_rmtif_ipaddr *top;
+ json_object *json_addr, *json_obj;
+ char buf[4];
int i, n;
if (TLV_SIZE(tlvh) > buf_size) {
@@ -3285,13 +3326,29 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
top = (struct te_link_subtlv_rmtif_ipaddr *)tlvh;
n = ntohs(tlvh->length) / sizeof(top->value[0]);
if (vty != NULL)
- vty_out(vty, " Remote Interface IP Address(es): %d\n", n);
+ if (!json)
+ vty_out(vty, " Remote Interface IP Address(es): %d\n",
+ n);
+ else {
+ json_addr = json_object_new_array();
+ json_object_object_add(json, "remoteIPAddresses",
+ json_addr);
+ }
else
zlog_debug(" Remote Interface IP Address(es): %d", n);
for (i = 0; i < n; i++) {
if (vty != NULL)
- vty_out(vty, " #%d: %pI4\n", i, &top->value[i]);
+ if (!json)
+ vty_out(vty, " #%d: %pI4\n", i,
+ &top->value[i]);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ json_object_string_addf(json_obj, buf, "%pI4",
+ &top->value[i]);
+ json_object_array_add(json_addr, json_obj);
+ }
else
zlog_debug(" #%d: %pI4", i, &top->value[i]);
}
@@ -3299,7 +3356,8 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_te_metric *top;
@@ -3307,8 +3365,12 @@ static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
top = (struct te_link_subtlv_te_metric *)tlvh;
if (vty != NULL)
- vty_out(vty, " Traffic Engineering Metric: %u\n",
- (uint32_t)ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Traffic Engineering Metric: %u\n",
+ (uint32_t)ntohl(top->value));
+ else
+ json_object_int_add(json, "teDefaultMetric",
+ (uint32_t)ntohl(top->value));
else
zlog_debug(" Traffic Engineering Metric: %u",
(uint32_t)ntohl(top->value));
@@ -3317,7 +3379,8 @@ static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_max_bw *top;
float fval;
@@ -3328,7 +3391,11 @@ static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval);
+ if (!json)
+ vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "maxLinkBandwidth", fval);
else
zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
@@ -3336,7 +3403,8 @@ static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_max_rsv_bw *top;
float fval;
@@ -3347,8 +3415,12 @@ static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "maxResvLinkBandwidth",
+ fval);
else
zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
fval);
@@ -3357,18 +3429,27 @@ static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_unrsv_bw *top;
+ json_object *json_bw, *json_obj;
float fval1, fval2;
+ char buf[16];
int i;
check_tlv_size(TE_LINK_SUBTLV_UNRSV_SIZE, "Unreserved Bandwidth");
top = (struct te_link_subtlv_unrsv_bw *)tlvh;
if (vty != NULL)
- vty_out(vty,
- " Unreserved Bandwidth per Class Type in Byte/s:\n");
+ if (!json)
+ vty_out(vty,
+ " Unreserved Bandwidth per Class Type in Byte/s:\n");
+ else {
+ json_bw = json_object_new_array();
+ json_object_object_add(json, "unreservedBandwidth",
+ json_bw);
+ }
else
zlog_debug(
" Unreserved Bandwidth per Class Type in Byte/s:");
@@ -3377,9 +3458,20 @@ static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
fval2 = ntohf(top->value[i + 1]);
if (vty != NULL)
- vty_out(vty,
- " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
- i, fval1, i + 1, fval2);
+ if (!json)
+ vty_out(vty,
+ " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
+ i, fval1, i + 1, fval2);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 12, "classType-%u", i);
+ json_object_double_add(json_obj, buf, fval1);
+ json_object_array_add(json_bw, json_obj);
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 12, "classType-%u", i + 1);
+ json_object_double_add(json_obj, buf, fval2);
+ json_object_array_add(json_bw, json_obj);
+ }
else
zlog_debug(
" [%d]: %g (Bytes/sec), [%d]: %g (Bytes/sec)",
@@ -3390,7 +3482,8 @@ static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_rsc_clsclr *top;
@@ -3398,8 +3491,13 @@ static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
top = (struct te_link_subtlv_rsc_clsclr *)tlvh;
if (vty != NULL)
- vty_out(vty, " Resource class/color: 0x%x\n",
- (uint32_t)ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Resource class/color: 0x%x\n",
+ (uint32_t)ntohl(top->value));
+ else
+ json_object_string_addf(json, "administrativeGroup",
+ "0x%x",
+ (uint32_t)ntohl(top->value));
else
zlog_debug(" Resource Class/Color: 0x%x",
(uint32_t)ntohl(top->value));
@@ -3408,7 +3506,8 @@ static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_lrrid *top;
@@ -3417,10 +3516,17 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
top = (struct te_link_subtlv_lrrid *)tlvh;
if (vty != NULL) {
- vty_out(vty, " Local TE Router ID: %pI4\n",
- &top->local);
- vty_out(vty, " Remote TE Router ID: %pI4\n",
- &top->remote);
+ if (!json) {
+ vty_out(vty, " Local TE Router ID: %pI4\n",
+ &top->local);
+ vty_out(vty, " Remote TE Router ID: %pI4\n",
+ &top->remote);
+ } else {
+ json_object_string_addf(json, "localTeRouterID", "%pI4",
+ &top->local);
+ json_object_string_addf(json, "remoteTeRouterID",
+ "%pI4", &top->remote);
+ }
} else {
zlog_debug(" Local TE Router ID: %pI4",
&top->local);
@@ -3432,7 +3538,8 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_llri *top;
@@ -3441,10 +3548,17 @@ static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
top = (struct te_link_subtlv_llri *)tlvh;
if (vty != NULL) {
- vty_out(vty, " Link Local ID: %d\n",
- (uint32_t)ntohl(top->local));
- vty_out(vty, " Link Remote ID: %d\n",
- (uint32_t)ntohl(top->remote));
+ if (!json) {
+ vty_out(vty, " Link Local ID: %d\n",
+ (uint32_t)ntohl(top->local));
+ vty_out(vty, " Link Remote ID: %d\n",
+ (uint32_t)ntohl(top->remote));
+ } else {
+ json_object_int_add(json, "localLinkID",
+ (uint32_t)ntohl(top->local));
+ json_object_int_add(json, "remoteLinkID",
+ (uint32_t)ntohl(top->remote));
+ }
} else {
zlog_debug(" Link Local ID: %d",
(uint32_t)ntohl(top->local));
@@ -3456,7 +3570,8 @@ static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_rip *top;
@@ -3465,8 +3580,12 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
top = (struct te_link_subtlv_rip *)tlvh;
if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote ASBR IP address: %pI4\n",
- &top->value);
+ if (!json)
+ vty_out(vty, " Inter-AS TE Remote ASBR IP address: %pI4\n",
+ &top->value);
+ else
+ json_object_string_addf(json, "remoteAsbrAddress",
+ "%pI4", &top->value);
else
zlog_debug(" Inter-AS TE Remote ASBR IP address: %pI4",
&top->value);
@@ -3475,7 +3594,8 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_ras *top;
@@ -3484,8 +3604,12 @@ static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
top = (struct te_link_subtlv_ras *)tlvh;
if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "remoteAsbrNumber",
+ ntohl(top->value));
else
zlog_debug(" Inter-AS TE Remote AS number: %u",
ntohl(top->value));
@@ -3494,7 +3618,8 @@ static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_av_delay *top;
uint32_t delay;
@@ -3507,8 +3632,15 @@ static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
anomalous = (uint32_t)ntohl(top->value) & TE_EXT_ANORMAL;
if (vty != NULL)
- vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
- anomalous ? "Anomalous" : "Normal", delay);
+ if (!json)
+ vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
+ anomalous ? "Anomalous" : "Normal", delay);
+ else {
+ json_object_int_add(json, "oneWayDelay", delay);
+ json_object_string_add(json, "oneWayDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Average Link Delay: %d (micro-sec)",
anomalous ? "Anomalous" : "Normal", delay);
@@ -3517,7 +3649,8 @@ static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_mm_delay *top;
uint32_t low, high;
@@ -3531,8 +3664,20 @@ static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
high = (uint32_t)ntohl(top->high);
if (vty != NULL)
- vty_out(vty, " %s Min/Max Link Delay: %d/%d (micro-sec)\n",
- anomalous ? "Anomalous" : "Normal", low, high);
+ if (!json)
+ vty_out(vty,
+ " %s Min/Max Link Delay: %d/%d (micro-sec)\n",
+ anomalous ? "Anomalous" : "Normal", low, high);
+ else {
+ json_object_int_add(json, "oneWayMinDelay", low);
+ json_object_string_add(json, "oneWayMinDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ json_object_int_add(json, "oneWayMaxDelay", high);
+ json_object_string_add(json, "oneWayMaxDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Min/Max Link Delay: %d/%d (micro-sec)",
anomalous ? "Anomalous" : "Normal", low, high);
@@ -3541,7 +3686,8 @@ static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_delay_var *top;
uint32_t jitter;
@@ -3552,7 +3698,12 @@ static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
jitter = (uint32_t)ntohl(top->value) & TE_EXT_MASK;
if (vty != NULL)
- vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter);
+ if (!json)
+ vty_out(vty, " Delay Variation: %d (micro-sec)\n",
+ jitter);
+ else
+ json_object_int_add(json, "oneWayDelayVariation",
+ jitter);
else
zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
@@ -3560,7 +3711,8 @@ static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_pkt_loss *top;
uint32_t loss;
@@ -3575,8 +3727,16 @@ static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
anomalous = (uint32_t)ntohl(top->value) & TE_EXT_ANORMAL;
if (vty != NULL)
- vty_out(vty, " %s Link Loss: %g (%%)\n",
- anomalous ? "Anomalous" : "Normal", fval);
+ if (!json)
+ vty_out(vty, " %s Link Loss: %g (%%)\n",
+ anomalous ? "Anomalous" : "Normal", fval);
+ else {
+ json_object_double_add(json, "oneWayPacketLoss", fval);
+ json_object_string_add(json,
+ "oneWayPacketLossNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Link Loss: %g (%%)",
anomalous ? "Anomalous" : "Normal", fval);
@@ -3585,7 +3745,8 @@ static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_res_bw *top;
float fval;
@@ -3596,9 +3757,13 @@ static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayResidualBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Residual Bandwidth: %g (Bytes/sec)",
@@ -3608,7 +3773,8 @@ static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_ava_bw *top;
float fval;
@@ -3619,9 +3785,13 @@ static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayAvailableBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Available Bandwidth: %g (Bytes/sec)",
@@ -3631,7 +3801,8 @@ static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_use_bw *top;
float fval;
@@ -3642,9 +3813,13 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayUtilizedBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
@@ -3654,8 +3829,10 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
if (vty != NULL)
vty_out(vty,
@@ -3669,8 +3846,17 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
else
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
ntohs(tlvh->type), ntohs(tlvh->length));
@@ -3680,7 +3866,8 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
struct tlv_header *tlvh0,
- uint16_t subtotal, uint16_t total)
+ uint16_t subtotal, uint16_t total,
+ json_object *json)
{
struct tlv_header *tlvh;
uint16_t sum = subtotal;
@@ -3688,69 +3875,72 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
for (tlvh = tlvh0; sum < total; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case TE_LINK_SUBTLV_LINK_TYPE:
- sum += show_vty_link_subtlv_link_type(vty, tlvh);
+ sum += show_vty_link_subtlv_link_type(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LINK_ID:
- sum += show_vty_link_subtlv_link_id(vty, tlvh);
+ sum += show_vty_link_subtlv_link_id(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LCLIF_IPADDR:
sum += show_vty_link_subtlv_lclif_ipaddr(vty, tlvh,
- total - sum);
+ total - sum,
+ json);
break;
case TE_LINK_SUBTLV_RMTIF_IPADDR:
sum += show_vty_link_subtlv_rmtif_ipaddr(vty, tlvh,
- total - sum);
+ total - sum,
+ json);
break;
case TE_LINK_SUBTLV_TE_METRIC:
- sum += show_vty_link_subtlv_te_metric(vty, tlvh);
+ sum += show_vty_link_subtlv_te_metric(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MAX_BW:
- sum += show_vty_link_subtlv_max_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_max_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MAX_RSV_BW:
- sum += show_vty_link_subtlv_max_rsv_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_max_rsv_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_UNRSV_BW:
- sum += show_vty_link_subtlv_unrsv_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_unrsv_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RSC_CLSCLR:
- sum += show_vty_link_subtlv_rsc_clsclr(vty, tlvh);
+ sum += show_vty_link_subtlv_rsc_clsclr(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LRRID:
- sum += show_vty_link_subtlv_lrrid(vty, tlvh);
+ sum += show_vty_link_subtlv_lrrid(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LLRI:
- sum += show_vty_link_subtlv_llri(vty, tlvh);
+ sum += show_vty_link_subtlv_llri(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RIP:
- sum += show_vty_link_subtlv_rip(vty, tlvh);
+ sum += show_vty_link_subtlv_rip(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RAS:
- sum += show_vty_link_subtlv_ras(vty, tlvh);
+ sum += show_vty_link_subtlv_ras(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_AV_DELAY:
- sum += show_vty_link_subtlv_av_delay(vty, tlvh);
+ sum += show_vty_link_subtlv_av_delay(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MM_DELAY:
- sum += show_vty_link_subtlv_mm_delay(vty, tlvh);
+ sum += show_vty_link_subtlv_mm_delay(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_DELAY_VAR:
- sum += show_vty_link_subtlv_delay_var(vty, tlvh);
+ sum += show_vty_link_subtlv_delay_var(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_PKT_LOSS:
- sum += show_vty_link_subtlv_pkt_loss(vty, tlvh);
+ sum += show_vty_link_subtlv_pkt_loss(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RES_BW:
- sum += show_vty_link_subtlv_res_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_res_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_AVA_BW:
- sum += show_vty_link_subtlv_ava_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_ava_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_USE_BW:
- sum += show_vty_link_subtlv_use_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_use_bw(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, total - sum,
+ json);
break;
}
}
@@ -3762,37 +3952,47 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json,
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh, *next;
- uint16_t sum, total;
+ uint16_t sum, sub, total;
uint16_t (*subfunc)(struct vty * vty, struct tlv_header * tlvh,
- uint16_t subtotal, uint16_t total) = NULL;
-
- if (json)
- return;
+ uint16_t subtotal, uint16_t total,
+ struct json_object *json) = NULL;
+ json_object *jobj = NULL;
sum = 0;
+ sub = 0;
total = lsa->size - OSPF_LSA_HEADER_SIZE;
for (tlvh = TLV_HDR_TOP(lsah); sum < total && tlvh;
tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) {
if (subfunc != NULL) {
- sum = (*subfunc)(vty, tlvh, sum, total);
+ sum = (*subfunc)(vty, tlvh, sum, total, jobj);
next = (struct tlv_header *)((char *)tlvh + sum);
subfunc = NULL;
continue;
}
next = NULL;
+ sub = total - sum;
switch (ntohs(tlvh->type)) {
case TE_TLV_ROUTER_ADDR:
- sum += show_vty_router_addr(vty, tlvh);
+ if (json) {
+ jobj = json_object_new_object();
+ json_object_object_add(json, "teRouterAddress",
+ jobj);
+ }
+ sum += show_vty_router_addr(vty, tlvh, jobj);
break;
case TE_TLV_LINK:
- sum += show_vty_link_header(vty, tlvh, total - sum);
+ if (json) {
+ jobj = json_object_new_object();
+ json_object_object_add(json, "teLink", jobj);
+ }
+ sum += show_vty_link_header(vty, tlvh, sub, jobj);
subfunc = ospf_mpls_te_show_link_subtlv;
next = TLV_DATA(tlvh);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, sub, json);
break;
}
}
@@ -4126,7 +4326,8 @@ DEFUN (show_ip_ospf_mpls_te_router,
if (ntohs(OspfMplsTE.router_addr.header.type) != 0)
show_vty_router_addr(vty,
- &OspfMplsTE.router_addr.header);
+ &OspfMplsTE.router_addr.header,
+ NULL);
else
vty_out(vty, " Router address is not set\n");
vty_out(vty, " Link State distribution is %s\n",
@@ -4135,7 +4336,8 @@ DEFUN (show_ip_ospf_mpls_te_router,
return CMD_SUCCESS;
}
-static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
+static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp,
+ json_object *json)
{
struct mpls_te_link *lp;
@@ -4165,53 +4367,69 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
if (TLV_TYPE(lp->link_type) != 0)
show_vty_link_subtlv_link_type(vty,
- &lp->link_type.header);
+ &lp->link_type.header,
+ json);
if (TLV_TYPE(lp->link_id) != 0)
- show_vty_link_subtlv_link_id(vty, &lp->link_id.header);
+ show_vty_link_subtlv_link_id(vty, &lp->link_id.header,
+ json);
if (TLV_TYPE(lp->lclif_ipaddr) != 0)
show_vty_link_subtlv_lclif_ipaddr(
vty, &lp->lclif_ipaddr.header,
- lp->lclif_ipaddr.header.length);
+ lp->lclif_ipaddr.header.length,
+ json);
if (TLV_TYPE(lp->rmtif_ipaddr) != 0)
show_vty_link_subtlv_rmtif_ipaddr(
vty, &lp->rmtif_ipaddr.header,
- lp->rmtif_ipaddr.header.length);
+ lp->rmtif_ipaddr.header.length,
+ json);
if (TLV_TYPE(lp->rip) != 0)
- show_vty_link_subtlv_rip(vty, &lp->rip.header);
+ show_vty_link_subtlv_rip(vty, &lp->rip.header, json);
if (TLV_TYPE(lp->ras) != 0)
- show_vty_link_subtlv_ras(vty, &lp->ras.header);
+ show_vty_link_subtlv_ras(vty, &lp->ras.header, json);
if (TLV_TYPE(lp->te_metric) != 0)
show_vty_link_subtlv_te_metric(vty,
- &lp->te_metric.header);
+ &lp->te_metric.header,
+ json);
if (TLV_TYPE(lp->max_bw) != 0)
- show_vty_link_subtlv_max_bw(vty, &lp->max_bw.header);
+ show_vty_link_subtlv_max_bw(vty, &lp->max_bw.header,
+ json);
if (TLV_TYPE(lp->max_rsv_bw) != 0)
show_vty_link_subtlv_max_rsv_bw(vty,
- &lp->max_rsv_bw.header);
+ &lp->max_rsv_bw.header,
+ json);
if (TLV_TYPE(lp->unrsv_bw) != 0)
show_vty_link_subtlv_unrsv_bw(vty,
- &lp->unrsv_bw.header);
+ &lp->unrsv_bw.header,
+ json);
if (TLV_TYPE(lp->rsc_clsclr) != 0)
show_vty_link_subtlv_rsc_clsclr(vty,
- &lp->rsc_clsclr.header);
+ &lp->rsc_clsclr.header,
+ json);
if (TLV_TYPE(lp->av_delay) != 0)
show_vty_link_subtlv_av_delay(vty,
- &lp->av_delay.header);
+ &lp->av_delay.header,
+ json);
if (TLV_TYPE(lp->mm_delay) != 0)
show_vty_link_subtlv_mm_delay(vty,
- &lp->mm_delay.header);
+ &lp->mm_delay.header,
+ json);
if (TLV_TYPE(lp->delay_var) != 0)
show_vty_link_subtlv_delay_var(vty,
- &lp->delay_var.header);
+ &lp->delay_var.header,
+ json);
if (TLV_TYPE(lp->pkt_loss) != 0)
show_vty_link_subtlv_pkt_loss(vty,
- &lp->pkt_loss.header);
+ &lp->pkt_loss.header,
+ json);
if (TLV_TYPE(lp->res_bw) != 0)
- show_vty_link_subtlv_res_bw(vty, &lp->res_bw.header);
+ show_vty_link_subtlv_res_bw(vty, &lp->res_bw.header,
+ json);
if (TLV_TYPE(lp->ava_bw) != 0)
- show_vty_link_subtlv_ava_bw(vty, &lp->ava_bw.header);
+ show_vty_link_subtlv_ava_bw(vty, &lp->ava_bw.header,
+ json);
if (TLV_TYPE(lp->use_bw) != 0)
- show_vty_link_subtlv_use_bw(vty, &lp->use_bw.header);
+ show_vty_link_subtlv_use_bw(vty, &lp->use_bw.header,
+ json);
vty_out(vty, "---------------\n\n");
} else {
vty_out(vty, " %s: MPLS-TE is disabled on this interface\n",
@@ -4240,7 +4458,6 @@ DEFUN (show_ip_ospf_mpls_te_link,
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL || !ospf->oi_running)
return CMD_SUCCESS;
-
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (!vrf)
return CMD_SUCCESS;
@@ -4254,11 +4471,11 @@ DEFUN (show_ip_ospf_mpls_te_link,
}
if (!ifp) {
FOR_ALL_INTERFACES (vrf, ifp)
- show_mpls_te_link_sub(vty, ifp);
+ show_mpls_te_link_sub(vty, ifp, NULL);
return CMD_SUCCESS;
}
- show_mpls_te_link_sub(vty, ifp);
+ show_mpls_te_link_sub(vty, ifp, NULL);
return CMD_SUCCESS;
}
diff --git a/tests/topotests/ospfapi/test_ospf_clientapi.py b/tests/topotests/ospfapi/test_ospf_clientapi.py
index 41c18df7d..49dd34d65 100644
--- a/tests/topotests/ospfapi/test_ospf_clientapi.py
+++ b/tests/topotests/ospfapi/test_ospf_clientapi.py
@@ -277,7 +277,9 @@ def _test_add_data(tgen, apibin):
"linkStateId": "230.0.0.2",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000001",
- "opaqueData": "00000202",
+ "opaqueValues": {
+ "opaqueData": "00000202"
+ }
},
],
}
@@ -327,7 +329,9 @@ def _test_add_data(tgen, apibin):
"linkStateId": "231.0.0.1",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000001",
- "opaqueData": "00010101",
+ "opaqueValues": {
+ "opaqueData": "00010101",
+ }
},
],
}
@@ -376,7 +380,9 @@ def _test_add_data(tgen, apibin):
"linkStateId": "232.0.0.3",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000001",
- "opaqueData": "deadbeaf01234567",
+ "opaqueValues": {
+ "opaqueData": "deadbeaf01234567",
+ }
},
]
}
@@ -427,7 +433,9 @@ def _test_add_data(tgen, apibin):
"linkStateId": "232.0.0.3",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000002",
- "opaqueData": "ebadf00d",
+ "opaqueValues": {
+ "opaqueData": "ebadf00d",
+ }
},
]
}
@@ -574,7 +582,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "76bf",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "230.0.0.2",
@@ -583,7 +591,7 @@ def _test_opaque_add_del(tgen, apibin):
"checksum": "8aa2",
"length": 24,
"opaqueId": 2,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
]
}
@@ -599,7 +607,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5bd8",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "231.0.0.2",
@@ -607,7 +615,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "7690",
"length": 28,
- "opaqueDataLength": 8,
+ "opaqueLength": 8,
},
],
},
@@ -621,7 +629,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5ed5",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "232.0.0.2",
@@ -629,7 +637,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "d9bd",
"length": 24,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
],
},
@@ -734,7 +742,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "76bf",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "230.0.0.2",
@@ -744,7 +752,7 @@ def _test_opaque_add_del(tgen, apibin):
"checksum": "8aa2",
"length": 24,
"opaqueId": 2,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
]
}
@@ -760,7 +768,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5bd8",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"lsaAge": 3600,
@@ -770,7 +778,7 @@ def _test_opaque_add_del(tgen, apibin):
"checksum": "4fe2",
# data removed
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
],
},
@@ -785,7 +793,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5ed5",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "232.0.0.2",
@@ -793,7 +801,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "d9bd",
"length": 24,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
],
},
@@ -827,7 +835,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "76bf",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "230.0.0.2",
@@ -837,7 +845,7 @@ def _test_opaque_add_del(tgen, apibin):
"checksum": "8aa2",
"length": 24,
"opaqueId": 2,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
]
}
@@ -854,7 +862,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5bd8",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"lsaAge": 3600,
@@ -864,7 +872,7 @@ def _test_opaque_add_del(tgen, apibin):
"checksum": "4fe2",
# data removed
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
],
},
@@ -879,7 +887,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "5ed5",
"length": 20,
- "opaqueDataLength": 0,
+ "opaqueLength": 0,
},
{
"linkStateId": "232.0.0.2",
@@ -888,7 +896,7 @@ def _test_opaque_add_del(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "d9bd",
"length": 24,
- "opaqueDataLength": 4,
+ "opaqueLength": 4,
},
],
},
@@ -1044,7 +1052,7 @@ def _test_opaque_add_restart_add(tgen, apibin):
"lsaSeqNumber": "80000001",
"checksum": "b07a",
"length": 28,
- "opaqueDataLength": 8,
+ "opaqueLength": 8,
},
],
},
@@ -1100,7 +1108,7 @@ def _test_opaque_add_restart_add(tgen, apibin):
"lsaSeqNumber": "80000003",
"checksum": "cb27",
"length": 28,
- "opaqueDataLength": 8,
+ "opaqueLength": 8,
},
],
},
@@ -1655,7 +1663,9 @@ def _test_opaque_link_local_lsa_crash(tgen, apibin):
"linkStateId": "230.0.0.1",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000001",
- "opaqueData": "feedaceedeadbeef",
+ "opaqueValues": {
+ "opaqueData": "feedaceedeadbeef",
+ }
},
],
}
@@ -1684,7 +1694,9 @@ def _test_opaque_link_local_lsa_crash(tgen, apibin):
"linkStateId": "230.0.0.1",
"advertisingRouter": "1.0.0.0",
"lsaSeqNumber": "80000001",
- "opaqueData": "feedaceecafebeef",
+ "opaqueValues": {
+ "opaqueData": "feedaceecafebeef",
+ }
},
],
}