forked from Mirror/frr
ospfd: Decode Router Info. TLVs for json output
When dumping ospf database with json output, decode Router Information TLVs and sub-TLVs. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
parent
95c9cb9aa9
commit
b27d9e4d3b
223
ospfd/ospf_ri.c
223
ospfd/ospf_ri.c
|
@ -24,6 +24,7 @@
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "sockunion.h" /* for inet_aton() */
|
#include "sockunion.h" /* for inet_aton() */
|
||||||
#include "mpls.h"
|
#include "mpls.h"
|
||||||
|
#include <lib/json.h>
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
|
@ -1216,15 +1217,20 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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;
|
struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
|
||||||
|
|
||||||
check_tlv_size(RI_TLV_CAPABILITIES_SIZE, "Router Capabilities");
|
check_tlv_size(RI_TLV_CAPABILITIES_SIZE, "Router Capabilities");
|
||||||
|
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " Router Capabilities: 0x%x\n",
|
vty_out(vty, " Router Capabilities: 0x%x\n",
|
||||||
ntohl(top->value));
|
ntohl(top->value));
|
||||||
|
else
|
||||||
|
json_object_string_addf(json, "routerCapabilities",
|
||||||
|
"0x%x", ntohl(top->value));
|
||||||
else
|
else
|
||||||
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_address *)tlvh;
|
(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) {
|
if (ntohs(top->address.type) == PCE_ADDRESS_IPV4) {
|
||||||
check_tlv_size(PCE_ADDRESS_IPV4_SIZE, "PCE Address");
|
check_tlv_size(PCE_ADDRESS_IPV4_SIZE, "PCE Address");
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " PCE Address: %pI4\n",
|
vty_out(vty, " PCE Address: %pI4\n",
|
||||||
&top->address.value);
|
&top->address.value);
|
||||||
|
else
|
||||||
|
json_object_string_addf(json, "pceAddress",
|
||||||
|
"%pI4",
|
||||||
|
&top->address.value);
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Address: %pI4",
|
zlog_debug(" PCE Address: %pI4",
|
||||||
&top->address.value);
|
&top->address.value);
|
||||||
} else if (ntohs(top->address.type) == PCE_ADDRESS_IPV6) {
|
} 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");
|
check_tlv_size(PCE_ADDRESS_IPV6_SIZE, "PCE Address");
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty, " PCE Address: 0x%x\n",
|
if (!json)
|
||||||
ntohl(top->address.value.s_addr));
|
vty_out(vty,
|
||||||
|
" PCE Address: unsupported IPv6\n");
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Address: 0x%x",
|
json_object_string_add(json, "pceAddress",
|
||||||
ntohl(top->address.value.s_addr));
|
"unsupported IPv6");
|
||||||
|
|
||||||
|
else
|
||||||
|
zlog_debug(" PCE Address: unsupported IPv6");
|
||||||
} else {
|
} else {
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty, " Wrong PCE Address type: 0x%x\n",
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_path_scope *)tlvh;
|
(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");
|
check_tlv_size(RI_PCE_SUBTLV_PATH_SCOPE_SIZE, "PCE Path Scope");
|
||||||
|
|
||||||
if (vty != NULL)
|
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
|
else
|
||||||
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
|
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,
|
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 ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
|
||||||
struct in_addr tmp;
|
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) {
|
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
|
||||||
tmp.s_addr = top->value;
|
tmp.s_addr = top->value;
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
|
vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
|
||||||
|
else
|
||||||
|
json_object_string_addf(json, "pceDomainArea",
|
||||||
|
"%pI4", &tmp);
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Domain Area: %pI4", &tmp);
|
zlog_debug(" PCE Domain Area: %pI4", &tmp);
|
||||||
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " PCE Domain AS: %d\n",
|
vty_out(vty, " PCE Domain AS: %d\n",
|
||||||
ntohl(top->value));
|
ntohl(top->value));
|
||||||
|
else
|
||||||
|
json_object_int_add(json, "pceDomainAS",
|
||||||
|
ntohl(top->value));
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
|
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
|
||||||
} else {
|
} 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,
|
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 =
|
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) {
|
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
|
||||||
tmp.s_addr = top->value;
|
tmp.s_addr = top->value;
|
||||||
if (vty != NULL)
|
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
|
else
|
||||||
zlog_debug(" PCE Neighbor Area: %pI4", &tmp);
|
zlog_debug(" PCE Neighbor Area: %pI4", &tmp);
|
||||||
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " PCE Neighbor AS: %d\n",
|
vty_out(vty, " PCE Neighbor AS: %d\n",
|
||||||
ntohl(top->value));
|
ntohl(top->value));
|
||||||
|
else
|
||||||
|
json_object_int_add(json, "pceNeighborAS",
|
||||||
|
ntohl(top->value));
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Neighbor AS: %d",
|
zlog_debug(" PCE Neighbor AS: %d",
|
||||||
ntohl(top->value));
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_cap_flag *)tlvh;
|
(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");
|
check_tlv_size(RI_PCE_SUBTLV_CAP_FLAG_SIZE, "PCE Capabilities");
|
||||||
|
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
|
vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
|
||||||
ntohl(top->value));
|
ntohl(top->value));
|
||||||
|
else
|
||||||
|
json_object_string_addf(json, "pceCapabilities",
|
||||||
|
"0x%x", ntohl(top->value));
|
||||||
else
|
else
|
||||||
zlog_debug(" PCE Capabilities Flag: 0x%x",
|
zlog_debug(" PCE Capabilities Flag: 0x%x",
|
||||||
ntohl(top->value));
|
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,
|
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 (TLV_SIZE(tlvh) > buf_size) {
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
|
@ -1383,8 +1430,18 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
if (!json)
|
||||||
|
vty_out(vty,
|
||||||
|
" Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
||||||
ntohs(tlvh->type), ntohs(tlvh->length));
|
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
|
else
|
||||||
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
|
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
|
||||||
ntohs(tlvh->type), ntohs(tlvh->length));
|
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,
|
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;
|
struct tlv_header *tlvh;
|
||||||
uint16_t length = ntohs(ri->length);
|
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)) {
|
for (tlvh = ri; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||||
switch (ntohs(tlvh->type)) {
|
switch (ntohs(tlvh->type)) {
|
||||||
case RI_PCE_SUBTLV_ADDRESS:
|
case RI_PCE_SUBTLV_ADDRESS:
|
||||||
sum += show_vty_pce_subtlv_address(vty, tlvh);
|
sum += show_vty_pce_subtlv_address(vty, tlvh, json);
|
||||||
break;
|
break;
|
||||||
case RI_PCE_SUBTLV_PATH_SCOPE:
|
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;
|
break;
|
||||||
case RI_PCE_SUBTLV_DOMAIN:
|
case RI_PCE_SUBTLV_DOMAIN:
|
||||||
sum += show_vty_pce_subtlv_domain(vty, tlvh);
|
sum += show_vty_pce_subtlv_domain(vty, tlvh, json);
|
||||||
break;
|
break;
|
||||||
case RI_PCE_SUBTLV_NEIGHBOR:
|
case RI_PCE_SUBTLV_NEIGHBOR:
|
||||||
sum += show_vty_pce_subtlv_neighbor(vty, tlvh);
|
sum += show_vty_pce_subtlv_neighbor(vty, tlvh, json);
|
||||||
break;
|
break;
|
||||||
case RI_PCE_SUBTLV_CAP_FLAG:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
|
||||||
|
json);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1433,23 +1491,29 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display Segment Routing Algorithm TLV information */
|
/* 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 *algo =
|
||||||
(struct ri_sr_tlv_sr_algorithm *)tlvh;
|
(struct ri_sr_tlv_sr_algorithm *)tlvh;
|
||||||
int i;
|
int i;
|
||||||
|
json_object *json_algo, *obj;
|
||||||
|
char buf[2];
|
||||||
|
|
||||||
check_tlv_size(ALGORITHM_COUNT, "Segment Routing Algorithm");
|
check_tlv_size(ALGORITHM_COUNT, "Segment Routing Algorithm");
|
||||||
|
|
||||||
if (vty != NULL) {
|
if (vty != NULL)
|
||||||
|
if (!json) {
|
||||||
vty_out(vty, " Segment Routing Algorithm TLV:\n");
|
vty_out(vty, " Segment Routing Algorithm TLV:\n");
|
||||||
for (i = 0; i < ntohs(algo->header.length); i++) {
|
for (i = 0; i < ntohs(algo->header.length); i++) {
|
||||||
switch (algo->value[i]) {
|
switch (algo->value[i]) {
|
||||||
case 0:
|
case 0:
|
||||||
vty_out(vty, " Algorithm %d: SPF\n", i);
|
vty_out(vty,
|
||||||
|
" Algorithm %d: SPF\n", i);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
vty_out(vty, " Algorithm %d: Strict SPF\n",
|
vty_out(vty,
|
||||||
|
" Algorithm %d: Strict SPF\n",
|
||||||
i);
|
i);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1460,6 +1524,29 @@ static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
||||||
zlog_debug(" Segment Routing Algorithm TLV:");
|
zlog_debug(" Segment Routing Algorithm TLV:");
|
||||||
for (i = 0; i < ntohs(algo->header.length); i++)
|
for (i = 0; i < ntohs(algo->header.length); i++)
|
||||||
switch (algo->value[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 */
|
/* 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 *range =
|
||||||
(struct ri_sr_tlv_sid_label_range *)tlvh;
|
(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");
|
check_tlv_size(RI_SR_TLV_LABEL_RANGE_SIZE, "SR Label Range");
|
||||||
|
|
||||||
if (vty != NULL) {
|
if (vty != NULL)
|
||||||
|
if (!json) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
" Segment Routing %s Range TLV:\n"
|
" Segment Routing %s Range TLV:\n"
|
||||||
" Range Size = %d\n"
|
" Range Size = %d\n"
|
||||||
" SID Label = %d\n\n",
|
" SID Label = %d\n\n",
|
||||||
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
|
ntohs(range->header.type) ==
|
||||||
|
RI_SR_TLV_SRGB_LABEL_RANGE
|
||||||
? "Global"
|
? "Global"
|
||||||
: "Local",
|
: "Local",
|
||||||
GET_RANGE_SIZE(ntohl(range->size)),
|
GET_RANGE_SIZE(ntohl(range->size)),
|
||||||
GET_LABEL(ntohl(range->lower.value)));
|
GET_LABEL(ntohl(range->lower.value)));
|
||||||
} else {
|
} 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(
|
zlog_debug(
|
||||||
" Segment Routing %s Range TLV: Range Size = %d SID Label = %d",
|
" Segment Routing %s Range TLV: Range Size = %d SID Label = %d",
|
||||||
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
|
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 */
|
/* 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;
|
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");
|
check_tlv_size(RI_SR_TLV_NODE_MSD_SIZE, "Node Maximum Stack Depth");
|
||||||
|
|
||||||
if (vty != NULL) {
|
if (vty != NULL)
|
||||||
|
if (!json)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
" Segment Routing MSD TLV:\n"
|
" Segment Routing MSD TLV:\n"
|
||||||
" Node Maximum Stack Depth = %d\n",
|
" Node Maximum Stack Depth = %d\n",
|
||||||
msd->value);
|
msd->value);
|
||||||
} else {
|
else
|
||||||
|
json_object_int_add(json, "nodeMsd", msd->value);
|
||||||
|
else
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" Segment Routing MSD TLV: Node Maximum Stack Depth = %d",
|
" Segment Routing MSD TLV: Node Maximum Stack Depth = %d",
|
||||||
msd->value);
|
msd->value);
|
||||||
}
|
|
||||||
|
|
||||||
return TLV_SIZE(tlvh);
|
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 lsa_header *lsah = lsa->data;
|
||||||
struct tlv_header *tlvh;
|
struct tlv_header *tlvh;
|
||||||
uint16_t length = 0, sum = 0;
|
uint16_t length = 0, sum = 0;
|
||||||
|
json_object *jri = NULL, *jpce = NULL, *jsr = NULL;
|
||||||
|
|
||||||
if (json)
|
if (json) {
|
||||||
return;
|
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 */
|
/* Initialize TLV browsing */
|
||||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
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)) {
|
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||||
switch (ntohs(tlvh->type)) {
|
switch (ntohs(tlvh->type)) {
|
||||||
case RI_TLV_CAPABILITIES:
|
case RI_TLV_CAPABILITIES:
|
||||||
sum += show_vty_router_cap(vty, tlvh);
|
sum += show_vty_router_cap(vty, tlvh, jri);
|
||||||
break;
|
break;
|
||||||
case RI_TLV_PCE:
|
case RI_TLV_PCE:
|
||||||
tlvh++;
|
tlvh++;
|
||||||
sum += TLV_HDR_SIZE;
|
sum += TLV_HDR_SIZE;
|
||||||
sum += show_vty_pce_info(vty, tlvh, length - sum);
|
sum += show_vty_pce_info(vty, tlvh, length - sum, jpce);
|
||||||
break;
|
break;
|
||||||
case RI_SR_TLV_SR_ALGORITHM:
|
case RI_SR_TLV_SR_ALGORITHM:
|
||||||
sum += show_vty_sr_algorithm(vty, tlvh);
|
sum += show_vty_sr_algorithm(vty, tlvh, jsr);
|
||||||
break;
|
break;
|
||||||
case RI_SR_TLV_SRGB_LABEL_RANGE:
|
case RI_SR_TLV_SRGB_LABEL_RANGE:
|
||||||
case RI_SR_TLV_SRLB_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;
|
break;
|
||||||
case RI_SR_TLV_NODE_MSD:
|
case RI_SR_TLV_NODE_MSD:
|
||||||
sum += show_vty_sr_msd(vty, tlvh);
|
sum += show_vty_sr_msd(vty, tlvh, jsr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sum += show_vty_unknown_tlv(vty, tlvh, length);
|
sum += show_vty_unknown_tlv(vty, tlvh, length, jri);
|
||||||
break;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2045,7 +2169,7 @@ DEFUN (show_ip_ospf_router_info,
|
||||||
|
|
||||||
if (OspfRI.enabled) {
|
if (OspfRI.enabled) {
|
||||||
vty_out(vty, "--- Router Information parameters ---\n");
|
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 {
|
} else {
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
|
@ -2074,27 +2198,32 @@ DEFUN (show_ip_opsf_router_info_pce,
|
||||||
|
|
||||||
if (pce->pce_address.header.type != 0)
|
if (pce->pce_address.header.type != 0)
|
||||||
show_vty_pce_subtlv_address(vty,
|
show_vty_pce_subtlv_address(vty,
|
||||||
&pce->pce_address.header);
|
&pce->pce_address.header,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (pce->pce_scope.header.type != 0)
|
if (pce->pce_scope.header.type != 0)
|
||||||
show_vty_pce_subtlv_path_scope(vty,
|
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)) {
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
||||||
if (domain->header.type != 0)
|
if (domain->header.type != 0)
|
||||||
show_vty_pce_subtlv_domain(vty,
|
show_vty_pce_subtlv_domain(vty,
|
||||||
&domain->header);
|
&domain->header,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
||||||
if (neighbor->header.type != 0)
|
if (neighbor->header.type != 0)
|
||||||
show_vty_pce_subtlv_neighbor(vty,
|
show_vty_pce_subtlv_neighbor(vty,
|
||||||
&neighbor->header);
|
&neighbor->header,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pce->pce_cap_flag.header.type != 0)
|
if (pce->pce_cap_flag.header.type != 0)
|
||||||
show_vty_pce_subtlv_cap_flag(vty,
|
show_vty_pce_subtlv_cap_flag(vty,
|
||||||
&pce->pce_cap_flag.header);
|
&pce->pce_cap_flag.header,
|
||||||
|
NULL);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, " PCE info is disabled on this router\n");
|
vty_out(vty, " PCE info is disabled on this router\n");
|
||||||
|
|
Loading…
Reference in a new issue