diff options
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_ext.c | 231 | ||||
| -rw-r--r-- | ospfd/ospf_ldp_sync.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.c | 17 | ||||
| -rw-r--r-- | ospfd/ospf_ri.c | 301 | ||||
| -rw-r--r-- | ospfd/ospf_te.c | 474 | 
5 files changed, 734 insertions, 291 deletions
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index d82c2146c7..df0b3b9081 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_ldp_sync.c b/ospfd/ospf_ldp_sync.c index 4aab880d22..d1ef85c9a6 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -774,7 +774,7 @@ DEFPY (no_ospf_mpls_ldp_sync,         "Disable MPLS LDP-IGP Sync\n")  {  	VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); -	ospf_ldp_sync_gbl_exit(ospf, false); +	ospf_ldp_sync_gbl_exit(ospf, true);  	return CMD_SUCCESS;  } diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 24a850c737..5d2d65658f 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 2466c6419b..dbe44f7be4 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;  } @@ -2053,7 +2177,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, @@ -2082,27 +2206,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 d203b5ef4d..a55a37a907 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,12 +3952,11 @@ 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;  	total = lsa->size - OSPF_LSA_HEADER_SIZE; @@ -3775,24 +3964,34 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json,  	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 +4325,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 +4335,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 +4366,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 +4457,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 +4470,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;  }  | 
