mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 18:42:23 +00:00
Merge pull request #8408 from Orange-OpenSource/TE
ospfd: Correct Coverity defects
This commit is contained in:
commit
1f25f6c768
@ -58,7 +58,7 @@
|
||||
|
||||
|
||||
/* For debugging only, will be removed */
|
||||
void api_opaque_lsa_print(struct lsa_header *data)
|
||||
void api_opaque_lsa_print(struct ospf_lsa *lsa)
|
||||
{
|
||||
struct opaque_lsa {
|
||||
struct lsa_header header;
|
||||
@ -69,11 +69,11 @@ void api_opaque_lsa_print(struct lsa_header *data)
|
||||
int opaquelen;
|
||||
int i;
|
||||
|
||||
ospf_lsa_header_dump(data);
|
||||
ospf_lsa_header_dump(lsa->data);
|
||||
|
||||
olsa = (struct opaque_lsa *)data;
|
||||
olsa = (struct opaque_lsa *)lsa->data;
|
||||
|
||||
opaquelen = ntohs(data->length) - OSPF_LSA_HEADER_SIZE;
|
||||
opaquelen = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
zlog_debug("apiserver_lsa_print: opaquelen=%d", opaquelen);
|
||||
|
||||
for (i = 0; i < opaquelen; i++) {
|
||||
@ -111,11 +111,16 @@ struct msg *msg_new(uint8_t msgtype, void *msgbody, uint32_t seqnum,
|
||||
struct msg *msg_dup(struct msg *msg)
|
||||
{
|
||||
struct msg *new;
|
||||
size_t size;
|
||||
|
||||
assert(msg);
|
||||
|
||||
size = ntohs(msg->hdr.msglen);
|
||||
if (size > OSPF_MAX_LSA_SIZE)
|
||||
return NULL;
|
||||
|
||||
new = msg_new(msg->hdr.msgtype, STREAM_DATA(msg->s),
|
||||
ntohl(msg->hdr.msgseq), ntohs(msg->hdr.msglen));
|
||||
ntohl(msg->hdr.msgseq), size);
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -400,7 +405,7 @@ struct msg *msg_read(int fd)
|
||||
}
|
||||
|
||||
/* Allocate new message */
|
||||
msg = msg_new(hdr.msgtype, buf, ntohl(hdr.msgseq), ntohs(hdr.msglen));
|
||||
msg = msg_new(hdr.msgtype, buf, ntohl(hdr.msgseq), bodylen);
|
||||
|
||||
return msg;
|
||||
}
|
||||
@ -408,29 +413,34 @@ struct msg *msg_read(int fd)
|
||||
int msg_write(int fd, struct msg *msg)
|
||||
{
|
||||
uint8_t buf[OSPF_API_MAX_MSG_SIZE];
|
||||
int l;
|
||||
uint16_t l;
|
||||
int wlen;
|
||||
|
||||
assert(msg);
|
||||
assert(msg->s);
|
||||
|
||||
/* Length of message including header */
|
||||
l = sizeof(struct apimsghdr) + ntohs(msg->hdr.msglen);
|
||||
/* Length of OSPF LSA payload */
|
||||
l = ntohs(msg->hdr.msglen);
|
||||
if (l > OSPF_MAX_LSA_SIZE) {
|
||||
zlog_warn("%s: wrong LSA size %d", __func__, l);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make contiguous memory buffer for message */
|
||||
memcpy(buf, &msg->hdr, sizeof(struct apimsghdr));
|
||||
memcpy(buf + sizeof(struct apimsghdr), STREAM_DATA(msg->s),
|
||||
ntohs(msg->hdr.msglen));
|
||||
memcpy(buf + sizeof(struct apimsghdr), STREAM_DATA(msg->s), l);
|
||||
|
||||
/* Total length of OSPF API Message */
|
||||
l += sizeof(struct apimsghdr);
|
||||
wlen = writen(fd, buf, l);
|
||||
if (wlen < 0) {
|
||||
zlog_warn("msg_write: writen %s", safe_strerror(errno));
|
||||
zlog_warn("%s: writen %s", __func__, safe_strerror(errno));
|
||||
return -1;
|
||||
} else if (wlen == 0) {
|
||||
zlog_warn("msg_write: Connection closed by peer");
|
||||
zlog_warn("%s: Connection closed by peer", __func__);
|
||||
return -1;
|
||||
} else if (wlen != l) {
|
||||
zlog_warn("msg_write: Cannot write API message");
|
||||
zlog_warn("%s: Cannot write API message", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -276,7 +276,7 @@ struct apimsg {
|
||||
*/
|
||||
|
||||
/* For debugging only. */
|
||||
extern void api_opaque_lsa_print(struct lsa_header *data);
|
||||
extern void api_opaque_lsa_print(struct ospf_lsa *lsa);
|
||||
|
||||
/* Messages sent by client */
|
||||
extern struct msg *new_msg_register_opaque_type(uint32_t seqnum, uint8_t ltype,
|
||||
|
@ -1156,6 +1156,7 @@ int ospf_apiserver_handle_register_event(struct ospf_apiserver *apiserv,
|
||||
struct msg_register_event *rmsg;
|
||||
int rc;
|
||||
uint32_t seqnum;
|
||||
size_t size;
|
||||
|
||||
rmsg = (struct msg_register_event *)STREAM_DATA(msg->s);
|
||||
|
||||
@ -1165,13 +1166,16 @@ int ospf_apiserver_handle_register_event(struct ospf_apiserver *apiserv,
|
||||
/* Free existing filter in apiserv. */
|
||||
XFREE(MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter);
|
||||
/* Alloc new space for filter. */
|
||||
size = ntohs(msg->hdr.msglen);
|
||||
if (size < OSPF_MAX_LSA_SIZE) {
|
||||
|
||||
apiserv->filter =
|
||||
XMALLOC(MTYPE_OSPF_APISERVER_MSGFILTER, ntohs(msg->hdr.msglen));
|
||||
apiserv->filter = XMALLOC(MTYPE_OSPF_APISERVER_MSGFILTER, size);
|
||||
|
||||
/* copy it over. */
|
||||
memcpy(apiserv->filter, &rmsg->filter, ntohs(msg->hdr.msglen));
|
||||
rc = OSPF_API_OK;
|
||||
/* copy it over. */
|
||||
memcpy(apiserv->filter, &rmsg->filter, size);
|
||||
rc = OSPF_API_OK;
|
||||
} else
|
||||
rc = OSPF_API_NOMEMORY;
|
||||
|
||||
/* Send a reply back to client with return code */
|
||||
rc = ospf_apiserver_send_reply(apiserv, seqnum, rc);
|
||||
|
@ -241,7 +241,7 @@ const char *ospf_timer_dump(struct thread *t, char *buf, size_t size)
|
||||
static void ospf_packet_hello_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
struct ospf_hello *hello;
|
||||
int i;
|
||||
int i, len;
|
||||
|
||||
hello = (struct ospf_hello *)stream_pnt(s);
|
||||
|
||||
@ -256,9 +256,9 @@ static void ospf_packet_hello_dump(struct stream *s, uint16_t length)
|
||||
zlog_debug(" DRouter %pI4", &hello->d_router);
|
||||
zlog_debug(" BDRouter %pI4", &hello->bd_router);
|
||||
|
||||
length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE;
|
||||
zlog_debug(" # Neighbors %d", length / 4);
|
||||
for (i = 0; length > 0; i++, length -= sizeof(struct in_addr))
|
||||
len = length - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE;
|
||||
zlog_debug(" # Neighbors %d", len / 4);
|
||||
for (i = 0; len > 0; i++, len -= sizeof(struct in_addr))
|
||||
zlog_debug(" Neighbor %pI4", &hello->neighbors[i]);
|
||||
}
|
||||
|
||||
@ -285,7 +285,8 @@ static void ospf_router_lsa_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
struct router_lsa *rl;
|
||||
int i, len;
|
||||
struct router_link *rlnk;
|
||||
int i, len, sum;
|
||||
|
||||
rl = (struct router_lsa *)stream_pnt(s);
|
||||
|
||||
@ -294,16 +295,15 @@ static void ospf_router_lsa_dump(struct stream *s, uint16_t length)
|
||||
ospf_router_lsa_flags_dump(rl->flags, buf, BUFSIZ));
|
||||
zlog_debug(" # links %d", ntohs(rl->links));
|
||||
|
||||
len = ntohs(rl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
|
||||
for (i = 0; len > 0; i++) {
|
||||
zlog_debug(" Link ID %pI4", &rl->link[i].link_id);
|
||||
zlog_debug(" Link Data %pI4",
|
||||
&rl->link[i].link_data);
|
||||
zlog_debug(" Type %d", (uint8_t)rl->link[i].type);
|
||||
zlog_debug(" TOS %d", (uint8_t)rl->link[i].tos);
|
||||
zlog_debug(" metric %d", ntohs(rl->link[i].metric));
|
||||
|
||||
len -= 12;
|
||||
len = length - OSPF_LSA_HEADER_SIZE - 4;
|
||||
rlnk = &rl->link[0];
|
||||
sum = 0;
|
||||
for (i = 0; sum < len && rlnk; sum += 12, rlnk = &rl->link[++i]) {
|
||||
zlog_debug(" Link ID %pI4", &rlnk->link_id);
|
||||
zlog_debug(" Link Data %pI4", &rlnk->link_data);
|
||||
zlog_debug(" Type %d", (uint8_t)rlnk->type);
|
||||
zlog_debug(" TOS %d", (uint8_t)rlnk->tos);
|
||||
zlog_debug(" metric %d", ntohs(rlnk->metric));
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,10 +312,11 @@ static void ospf_network_lsa_dump(struct stream *s, uint16_t length)
|
||||
struct network_lsa *nl;
|
||||
int i, cnt;
|
||||
|
||||
nl = (struct network_lsa *)stream_pnt(s);
|
||||
cnt = (ntohs(nl->header.length) - (OSPF_LSA_HEADER_SIZE + 4)) / 4;
|
||||
|
||||
zlog_debug(" Network-LSA");
|
||||
|
||||
nl = (struct network_lsa *)stream_pnt(s);
|
||||
cnt = (length - (OSPF_LSA_HEADER_SIZE + 4)) / 4;
|
||||
|
||||
/*
|
||||
zlog_debug ("LSA total size %d", ntohs (nl->header.length));
|
||||
zlog_debug ("Network-LSA size %d",
|
||||
@ -331,55 +332,53 @@ static void ospf_network_lsa_dump(struct stream *s, uint16_t length)
|
||||
static void ospf_summary_lsa_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
struct summary_lsa *sl;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
sl = (struct summary_lsa *)stream_pnt(s);
|
||||
|
||||
zlog_debug(" Summary-LSA");
|
||||
zlog_debug(" Network Mask %pI4", &sl->mask);
|
||||
|
||||
size = ntohs(sl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
|
||||
for (i = 0; size > 0; size -= 4, i++)
|
||||
zlog_debug(" TOS=%d metric %d", sl->tos,
|
||||
GET_METRIC(sl->metric));
|
||||
zlog_debug(" TOS=%d metric %d", sl->tos, GET_METRIC(sl->metric));
|
||||
}
|
||||
|
||||
static void ospf_as_external_lsa_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
struct as_external_lsa *al;
|
||||
int size;
|
||||
struct as_route *asr;
|
||||
int size, sum;
|
||||
int i;
|
||||
|
||||
al = (struct as_external_lsa *)stream_pnt(s);
|
||||
zlog_debug(" %s", ospf_lsa_type_msg[al->header.type].str);
|
||||
zlog_debug(" Network Mask %pI4", &al->mask);
|
||||
|
||||
size = ntohs(al->header.length) - OSPF_LSA_HEADER_SIZE - 4;
|
||||
for (i = 0; size > 0; size -= 12, i++) {
|
||||
size = length - OSPF_LSA_HEADER_SIZE - 4;
|
||||
asr = &al->e[0];
|
||||
sum = 0;
|
||||
for (i = 0; sum < size && asr; sum += 12, asr = &al->e[++i]) {
|
||||
zlog_debug(" bit %s TOS=%d metric %d",
|
||||
IS_EXTERNAL_METRIC(al->e[i].tos) ? "E" : "-",
|
||||
al->e[i].tos & 0x7f, GET_METRIC(al->e[i].metric));
|
||||
zlog_debug(" Forwarding address %pI4",
|
||||
&al->e[i].fwd_addr);
|
||||
IS_EXTERNAL_METRIC(asr->tos) ? "E" : "-",
|
||||
asr->tos & 0x7f, GET_METRIC(asr->metric));
|
||||
zlog_debug(" Forwarding address %pI4", &asr->fwd_addr);
|
||||
zlog_debug(" External Route Tag %" ROUTE_TAG_PRI,
|
||||
al->e[i].route_tag);
|
||||
asr->route_tag);
|
||||
}
|
||||
}
|
||||
|
||||
static void ospf_lsa_header_list_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
struct lsa_header *lsa;
|
||||
int len;
|
||||
|
||||
zlog_debug(" # LSA Headers %d", length / OSPF_LSA_HEADER_SIZE);
|
||||
|
||||
/* LSA Headers. */
|
||||
while (length > 0) {
|
||||
len = length;
|
||||
while (len > 0) {
|
||||
lsa = (struct lsa_header *)stream_pnt(s);
|
||||
ospf_lsa_header_dump(lsa);
|
||||
|
||||
stream_forward_getp(s, OSPF_LSA_HEADER_SIZE);
|
||||
length -= OSPF_LSA_HEADER_SIZE;
|
||||
len -= OSPF_LSA_HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,6 +416,7 @@ static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length)
|
||||
uint32_t ls_type;
|
||||
struct in_addr ls_id;
|
||||
struct in_addr adv_router;
|
||||
int sum;
|
||||
|
||||
sp = stream_get_getp(s);
|
||||
|
||||
@ -425,7 +425,8 @@ static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length)
|
||||
zlog_debug("Link State Request");
|
||||
zlog_debug(" # Requests %d", length / 12);
|
||||
|
||||
for (; length > 0; length -= 12) {
|
||||
sum = 0;
|
||||
for (; sum < length; sum += 12) {
|
||||
ls_type = stream_getl(s);
|
||||
ls_id.s_addr = stream_get_ipv4(s);
|
||||
adv_router.s_addr = stream_get_ipv4(s);
|
||||
@ -442,23 +443,23 @@ static void ospf_packet_ls_upd_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
uint32_t sp;
|
||||
struct lsa_header *lsa;
|
||||
int lsa_len;
|
||||
int lsa_len, len;
|
||||
uint32_t count;
|
||||
|
||||
length -= OSPF_HEADER_SIZE;
|
||||
len = length - OSPF_HEADER_SIZE;
|
||||
|
||||
sp = stream_get_getp(s);
|
||||
|
||||
count = stream_getl(s);
|
||||
length -= 4;
|
||||
len -= 4;
|
||||
|
||||
zlog_debug("Link State Update");
|
||||
zlog_debug(" # LSAs %d", count);
|
||||
|
||||
while (length > 0 && count > 0) {
|
||||
if (length < OSPF_HEADER_SIZE || length % 4 != 0) {
|
||||
while (len > 0 && count > 0) {
|
||||
if ((uint16_t)len < OSPF_LSA_HEADER_SIZE || len % 4 != 0) {
|
||||
zlog_debug(" Remaining %d bytes; Incorrect length.",
|
||||
length);
|
||||
len);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -466,34 +467,39 @@ static void ospf_packet_ls_upd_dump(struct stream *s, uint16_t length)
|
||||
lsa_len = ntohs(lsa->length);
|
||||
ospf_lsa_header_dump(lsa);
|
||||
|
||||
/* Check that LSA length is valid */
|
||||
if (lsa_len > len || lsa_len % 4 != 0) {
|
||||
zlog_debug(" LSA length %d is incorrect!", lsa_len);
|
||||
break;
|
||||
}
|
||||
switch (lsa->type) {
|
||||
case OSPF_ROUTER_LSA:
|
||||
ospf_router_lsa_dump(s, length);
|
||||
ospf_router_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
case OSPF_NETWORK_LSA:
|
||||
ospf_network_lsa_dump(s, length);
|
||||
ospf_network_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
case OSPF_SUMMARY_LSA:
|
||||
case OSPF_ASBR_SUMMARY_LSA:
|
||||
ospf_summary_lsa_dump(s, length);
|
||||
ospf_summary_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
case OSPF_AS_EXTERNAL_LSA:
|
||||
ospf_as_external_lsa_dump(s, length);
|
||||
ospf_as_external_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
case OSPF_AS_NSSA_LSA:
|
||||
ospf_as_external_lsa_dump(s, length);
|
||||
ospf_as_external_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
case OSPF_OPAQUE_LINK_LSA:
|
||||
case OSPF_OPAQUE_AREA_LSA:
|
||||
case OSPF_OPAQUE_AS_LSA:
|
||||
ospf_opaque_lsa_dump(s, length);
|
||||
ospf_opaque_lsa_dump(s, lsa_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
stream_forward_getp(s, lsa_len);
|
||||
length -= lsa_len;
|
||||
len -= lsa_len;
|
||||
count--;
|
||||
}
|
||||
|
||||
|
@ -1715,13 +1715,23 @@ static void ospf_ext_lsa_schedule(struct ext_itf *exti, enum lsa_opcode op)
|
||||
* ------------------------------------
|
||||
*/
|
||||
|
||||
#define check_tlv_size(size, msg) \
|
||||
do { \
|
||||
if (ntohs(tlvh->length) != size) { \
|
||||
vty_out(vty, " Wrong %s TLV size: %d(%d). Abort!\n", \
|
||||
msg, ntohs(tlvh->length), size); \
|
||||
return size + TLV_HDR_SIZE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Cisco experimental SubTLV */
|
||||
static uint16_t show_vty_ext_link_rmt_itf_addr(struct vty *vty,
|
||||
struct tlv_header *tlvh)
|
||||
{
|
||||
struct ext_subtlv_rmt_itf_addr *top;
|
||||
struct ext_subtlv_rmt_itf_addr *top =
|
||||
(struct ext_subtlv_rmt_itf_addr *)tlvh;
|
||||
|
||||
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",
|
||||
@ -1736,6 +1746,8 @@ static uint16_t show_vty_ext_link_adj_sid(struct vty *vty,
|
||||
{
|
||||
struct ext_subtlv_adj_sid *top = (struct ext_subtlv_adj_sid *)tlvh;
|
||||
|
||||
check_tlv_size(EXT_SUBTLV_ADJ_SID_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,
|
||||
@ -1755,6 +1767,8 @@ static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
|
||||
struct ext_subtlv_lan_adj_sid *top =
|
||||
(struct ext_subtlv_lan_adj_sid *)tlvh;
|
||||
|
||||
check_tlv_size(EXT_SUBTLV_LAN_ADJ_SID_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,
|
||||
@ -1768,8 +1782,15 @@ static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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));
|
||||
|
||||
@ -1777,13 +1798,22 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh)
|
||||
}
|
||||
|
||||
/* Extended Link Sub TLVs */
|
||||
static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext)
|
||||
static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct ext_tlv_link *top = (struct ext_tlv_link *)ext;
|
||||
struct tlv_header *tlvh;
|
||||
uint16_t length = ntohs(top->header.length) - 3 * sizeof(uint32_t);
|
||||
uint16_t length = ntohs(top->header.length);
|
||||
uint16_t sum = 0;
|
||||
|
||||
/* Verify that TLV length is valid against remaining buffer size */
|
||||
if (length > buf_size) {
|
||||
vty_out(vty,
|
||||
" Extended Link TLV size %d exceeds buffer size. Abort!\n",
|
||||
length);
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
vty_out(vty,
|
||||
" Extended Link TLV: Length %u\n Link Type: 0x%x\n"
|
||||
" Link ID: %pI4\n",
|
||||
@ -1791,9 +1821,11 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext)
|
||||
&top->link_id);
|
||||
vty_out(vty, " Link data: %pI4\n", &top->link_data);
|
||||
|
||||
/* Skip Extended TLV and parse sub-TLVs */
|
||||
length -= EXT_TLV_LINK_SIZE;
|
||||
tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
|
||||
+ EXT_TLV_LINK_SIZE);
|
||||
for (; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
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);
|
||||
@ -1805,7 +1837,7 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext)
|
||||
sum += show_vty_ext_link_rmt_itf_addr(vty, tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1821,16 +1853,16 @@ static void ospf_ext_link_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
uint16_t length = 0, sum = 0;
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
switch (ntohs(tlvh->type)) {
|
||||
case EXT_TLV_LINK:
|
||||
sum += show_vty_link_info(vty, tlvh);
|
||||
sum += show_vty_link_info(vty, tlvh, length - sum);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1843,6 +1875,8 @@ static uint16_t show_vty_ext_pref_pref_sid(struct vty *vty,
|
||||
struct ext_subtlv_prefix_sid *top =
|
||||
(struct ext_subtlv_prefix_sid *)tlvh;
|
||||
|
||||
check_tlv_size(EXT_SUBTLV_PREFIX_SID_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,
|
||||
@ -1857,28 +1891,39 @@ static uint16_t show_vty_ext_pref_pref_sid(struct vty *vty,
|
||||
}
|
||||
|
||||
/* Extended Prefix SubTLVs */
|
||||
static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext)
|
||||
static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct ext_tlv_prefix *top = (struct ext_tlv_prefix *)ext;
|
||||
struct tlv_header *tlvh;
|
||||
uint16_t length = ntohs(top->header.length) - 2 * sizeof(uint32_t);
|
||||
uint16_t length = ntohs(top->header.length);
|
||||
uint16_t sum = 0;
|
||||
|
||||
/* Verify that TLV length is valid against remaining buffer size */
|
||||
if (length > buf_size) {
|
||||
vty_out(vty,
|
||||
" Extended Link TLV size %d exceeds buffer size. Abort!\n",
|
||||
length);
|
||||
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);
|
||||
|
||||
/* Skip Extended Prefix TLV and parse sub-TLVs */
|
||||
length -= EXT_TLV_PREFIX_SIZE;
|
||||
tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
|
||||
+ EXT_TLV_PREFIX_SIZE);
|
||||
for (; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1894,16 +1939,16 @@ static void ospf_ext_pref_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
uint16_t length = 0, sum = 0;
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
switch (ntohs(tlvh->type)) {
|
||||
case EXT_TLV_PREFIX:
|
||||
sum += show_vty_pref_info(vty, tlvh);
|
||||
sum += show_vty_pref_info(vty, tlvh, length - sum);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -233,19 +233,17 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
|
||||
|
||||
lsah = (struct lsa_header *)lsa->data;
|
||||
|
||||
length = ntohs(lsah->length);
|
||||
|
||||
/* Check LSA len */
|
||||
if (length <= OSPF_LSA_HEADER_SIZE) {
|
||||
if (lsa->size <= OSPF_LSA_HEADER_SIZE) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
zlog_debug("%s: Malformed packet: Invalid LSA len:%d",
|
||||
__func__, length);
|
||||
return OSPF_GR_FAILURE;
|
||||
}
|
||||
|
||||
length -= OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
|
||||
/* Check TLV len against overall LSA */
|
||||
@ -996,18 +994,16 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
|
||||
lsah = (struct lsa_header *)lsa->data;
|
||||
|
||||
length = ntohs(lsah->length);
|
||||
|
||||
if (length <= OSPF_LSA_HEADER_SIZE) {
|
||||
if (lsa->size <= OSPF_LSA_HEADER_SIZE) {
|
||||
vty_out(vty, "%% Invalid LSA length: %d\n", length);
|
||||
return;
|
||||
}
|
||||
|
||||
length -= OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
vty_out(vty, " TLV info:\n");
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
/* Check TLV len */
|
||||
if (sum + TLV_SIZE(tlvh) > length) {
|
||||
|
@ -175,6 +175,7 @@ struct ospf_lsa *ospf_lsa_new_and_data(size_t size)
|
||||
|
||||
new = ospf_lsa_new();
|
||||
new->data = ospf_lsa_data_new(size);
|
||||
new->size = size;
|
||||
|
||||
return new;
|
||||
}
|
||||
@ -3241,22 +3242,22 @@ int ospf_lsa_different(struct ospf_lsa *l1, struct ospf_lsa *l2)
|
||||
if (IS_LSA_MAXAGE(l2) && !IS_LSA_MAXAGE(l1))
|
||||
return 1;
|
||||
|
||||
if (l1->data->length != l2->data->length)
|
||||
if (l1->size != l2->size)
|
||||
return 1;
|
||||
|
||||
if (l1->data->length == 0)
|
||||
if (l1->size == 0)
|
||||
return 1;
|
||||
|
||||
if (CHECK_FLAG((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
|
||||
return 1; /* May be a stale LSA in the LSBD */
|
||||
|
||||
assert(ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
|
||||
assert(l1->size > OSPF_LSA_HEADER_SIZE);
|
||||
|
||||
p1 = (char *)l1->data;
|
||||
p2 = (char *)l2->data;
|
||||
|
||||
if (memcmp(p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
|
||||
ntohs(l1->data->length) - OSPF_LSA_HEADER_SIZE)
|
||||
l1->size - OSPF_LSA_HEADER_SIZE)
|
||||
!= 0)
|
||||
return 1;
|
||||
|
||||
|
@ -84,8 +84,9 @@ struct ospf_lsa {
|
||||
#define OSPF_LSA_PREMATURE_AGE 0x40
|
||||
#define OSPF_LSA_IN_MAXAGE 0x80
|
||||
|
||||
/* LSA data. */
|
||||
/* LSA data. and size */
|
||||
struct lsa_header *data;
|
||||
size_t size;
|
||||
|
||||
/* Received time stamp. */
|
||||
struct timeval tv_recv;
|
||||
@ -168,7 +169,7 @@ struct router_lsa {
|
||||
uint8_t flags;
|
||||
uint8_t zero;
|
||||
uint16_t links;
|
||||
struct {
|
||||
struct router_link {
|
||||
struct in_addr link_id;
|
||||
struct in_addr link_data;
|
||||
uint8_t type;
|
||||
@ -199,7 +200,7 @@ struct summary_lsa {
|
||||
struct as_external_lsa {
|
||||
struct lsa_header header;
|
||||
struct in_addr mask;
|
||||
struct {
|
||||
struct as_route {
|
||||
uint8_t tos;
|
||||
uint8_t metric[3];
|
||||
struct in_addr fwd_addr;
|
||||
|
@ -1204,9 +1204,10 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
|
||||
|
||||
void ospf_opaque_lsa_dump(struct stream *s, uint16_t length)
|
||||
{
|
||||
struct ospf_lsa lsa;
|
||||
struct ospf_lsa lsa = {};
|
||||
|
||||
lsa.data = (struct lsa_header *)stream_pnt(s);
|
||||
lsa.size = length;
|
||||
show_opaque_info_detail(NULL, &lsa, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -79,6 +79,7 @@
|
||||
|
||||
#define VALID_OPAQUE_INFO_LEN(lsahdr) \
|
||||
((ntohs((lsahdr)->length) >= sizeof(struct lsa_header)) \
|
||||
&& ((ntohs((lsahdr)->length) < OSPF_MAX_LSA_SIZE)) \
|
||||
&& ((ntohs((lsahdr)->length) % sizeof(uint32_t)) == 0))
|
||||
|
||||
/*
|
||||
|
127
ospfd/ospf_ri.c
127
ospfd/ospf_ri.c
@ -294,8 +294,8 @@ static void set_pce_address(struct in_addr ipv4, struct ospf_pce_info *pce)
|
||||
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
||||
/* Set PCE Address */
|
||||
pce->pce_address.header.type = htons(RI_PCE_SUBTLV_ADDRESS);
|
||||
pce->pce_address.header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
|
||||
pce->pce_address.address.type = htons(PCE_ADDRESS_TYPE_IPV4);
|
||||
pce->pce_address.header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
||||
pce->pce_address.address.type = htons(PCE_ADDRESS_IPV4);
|
||||
pce->pce_address.address.value = ipv4;
|
||||
|
||||
return;
|
||||
@ -323,7 +323,7 @@ static void set_pce_domain(uint16_t type, uint32_t domain,
|
||||
sizeof(struct ri_pce_subtlv_domain));
|
||||
|
||||
new->header.type = htons(RI_PCE_SUBTLV_DOMAIN);
|
||||
new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
|
||||
new->header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
||||
new->type = htons(type);
|
||||
new->value = htonl(domain);
|
||||
|
||||
@ -369,7 +369,7 @@ static void set_pce_neighbor(uint16_t type, uint32_t domain,
|
||||
sizeof(struct ri_pce_subtlv_neighbor));
|
||||
|
||||
new->header.type = htons(RI_PCE_SUBTLV_NEIGHBOR);
|
||||
new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4);
|
||||
new->header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
||||
new->type = htons(type);
|
||||
new->value = htonl(domain);
|
||||
|
||||
@ -1226,10 +1226,25 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
|
||||
* Followings are vty session control functions.
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
#define check_tlv_size(size, msg) \
|
||||
do { \
|
||||
if (ntohs(tlvh->length) > size) { \
|
||||
if (vty != NULL) \
|
||||
vty_out(vty, " Wrong %s TLV size: %d(%d)\n", \
|
||||
msg, ntohs(tlvh->length), size); \
|
||||
else \
|
||||
zlog_debug(" Wrong %s TLV size: %d(%d)\n", \
|
||||
msg, ntohs(tlvh->length), size); \
|
||||
return size + TLV_HDR_SIZE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
|
||||
{
|
||||
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));
|
||||
@ -1245,21 +1260,30 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
|
||||
struct ri_pce_subtlv_address *top =
|
||||
(struct ri_pce_subtlv_address *)tlvh;
|
||||
|
||||
if (ntohs(top->address.type) == PCE_ADDRESS_TYPE_IPV4) {
|
||||
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);
|
||||
else
|
||||
zlog_debug(" PCE Address: %pI4",
|
||||
&top->address.value);
|
||||
} else {
|
||||
} 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));
|
||||
else
|
||||
zlog_debug(" PCE Address: 0x%x",
|
||||
ntohl(top->address.value.s_addr));
|
||||
} else {
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Wrong PCE Address type: 0x%x\n",
|
||||
ntohl(top->address.type));
|
||||
else
|
||||
zlog_debug(" Wrong PCE Address type: 0x%x",
|
||||
ntohl(top->address.type));
|
||||
}
|
||||
|
||||
return TLV_SIZE(tlvh);
|
||||
@ -1271,6 +1295,8 @@ static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
|
||||
struct ri_pce_subtlv_path_scope *top =
|
||||
(struct ri_pce_subtlv_path_scope *)tlvh;
|
||||
|
||||
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));
|
||||
else
|
||||
@ -1285,19 +1311,29 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
|
||||
struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
|
||||
struct in_addr tmp;
|
||||
|
||||
check_tlv_size(RI_PCE_SUBTLV_DOMAIN_SIZE, "PCE Domain");
|
||||
|
||||
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);
|
||||
vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
|
||||
else
|
||||
zlog_debug(" PCE domain Area: %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",
|
||||
vty_out(vty, " PCE Domain AS: %d\n",
|
||||
ntohl(top->value));
|
||||
else
|
||||
zlog_debug(" PCE domain AS: %d", ntohl(top->value));
|
||||
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
|
||||
} else {
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Wrong PCE Domain type: %d\n",
|
||||
ntohl(top->type));
|
||||
else
|
||||
zlog_debug(" Wrong PCE Domain type: %d",
|
||||
ntohl(top->type));
|
||||
}
|
||||
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
@ -1309,21 +1345,30 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
|
||||
(struct ri_pce_subtlv_neighbor *)tlvh;
|
||||
struct in_addr tmp;
|
||||
|
||||
check_tlv_size(RI_PCE_SUBTLV_NEIGHBOR_SIZE, "PCE Neighbor");
|
||||
|
||||
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);
|
||||
vty_out(vty, " PCE Neighbor Area: %pI4\n", &tmp);
|
||||
else
|
||||
zlog_debug(" PCE neighbor Area: %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",
|
||||
vty_out(vty, " PCE Neighbor AS: %d\n",
|
||||
ntohl(top->value));
|
||||
else
|
||||
zlog_debug(" PCE neighbor AS: %d",
|
||||
zlog_debug(" PCE Neighbor AS: %d",
|
||||
ntohl(top->value));
|
||||
} else {
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Wrong PCE Neighbor type: %d\n",
|
||||
ntohl(top->type));
|
||||
else
|
||||
zlog_debug(" Wrong PCE Neighbor type: %d",
|
||||
ntohl(top->type));
|
||||
}
|
||||
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
@ -1333,6 +1378,8 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
|
||||
struct ri_pce_subtlv_cap_flag *top =
|
||||
(struct ri_pce_subtlv_cap_flag *)tlvh;
|
||||
|
||||
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));
|
||||
@ -1343,8 +1390,21 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (TLV_SIZE(tlvh) > buf_size) {
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
else
|
||||
zlog_debug(
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
||||
ntohs(tlvh->type), ntohs(tlvh->length));
|
||||
@ -1356,12 +1416,21 @@ 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,
|
||||
uint32_t total)
|
||||
size_t buf_size)
|
||||
{
|
||||
struct tlv_header *tlvh;
|
||||
uint16_t length = ntohs(ri->length);
|
||||
uint16_t sum = 0;
|
||||
|
||||
for (tlvh = ri; sum < total; tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
/* Verify that TLV length is valid against remaining buffer size */
|
||||
if (length > buf_size) {
|
||||
vty_out(vty,
|
||||
" PCE Info TLV size %d exceeds buffer size. Abort!\n",
|
||||
length);
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1379,7 +1448,7 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
|
||||
sum += show_vty_pce_subtlv_cap_flag(vty, tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1393,6 +1462,8 @@ static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
|
||||
(struct ri_sr_tlv_sr_algorithm *)tlvh;
|
||||
int i;
|
||||
|
||||
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++) {
|
||||
@ -1411,9 +1482,7 @@ static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
zlog_debug(" Segment Routing Algorithm TLV:");
|
||||
for (i = 0; i < ntohs(algo->header.length); i++)
|
||||
switch (algo->value[i]) {
|
||||
@ -1439,6 +1508,8 @@ static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
|
||||
struct ri_sr_tlv_sid_label_range *range =
|
||||
(struct ri_sr_tlv_sid_label_range *)tlvh;
|
||||
|
||||
check_tlv_size(RI_SR_TLV_LABEL_RANGE_SIZE, "SR Label Range");
|
||||
|
||||
if (vty != NULL) {
|
||||
vty_out(vty,
|
||||
" Segment Routing %s Range TLV:\n"
|
||||
@ -1467,6 +1538,8 @@ static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *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");
|
||||
|
||||
if (vty != NULL) {
|
||||
vty_out(vty,
|
||||
" Segment Routing MSD TLV:\n"
|
||||
@ -1488,9 +1561,9 @@ static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
uint16_t length = 0, sum = 0;
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
switch (ntohs(tlvh->type)) {
|
||||
case RI_TLV_CAPABILITIES:
|
||||
@ -1513,7 +1586,7 @@ static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
break;
|
||||
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@
|
||||
|
||||
/* RFC4970: Router Information Capabilities TLV */ /* Mandatory */
|
||||
#define RI_TLV_CAPABILITIES 1
|
||||
|
||||
#define RI_TLV_CAPABILITIES_SIZE 4
|
||||
struct ri_tlv_router_cap {
|
||||
struct tlv_header header; /* Value length is 4 bytes. */
|
||||
uint32_t value;
|
||||
@ -105,12 +105,12 @@ struct ri_tlv_pce {
|
||||
struct ri_pce_subtlv_address {
|
||||
/* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */
|
||||
struct tlv_header header;
|
||||
#define PCE_ADDRESS_LENGTH_IPV4 8
|
||||
#define PCE_ADDRESS_LENGTH_IPV6 20
|
||||
#define PCE_ADDRESS_IPV4_SIZE 8
|
||||
#define PCE_ADDRESS_IPV6_SIZE 20
|
||||
struct {
|
||||
uint16_t type; /* Address type: 1 = IPv4, 2 = IPv6 */
|
||||
#define PCE_ADDRESS_TYPE_IPV4 1
|
||||
#define PCE_ADDRESS_TYPE_IPV6 2
|
||||
#define PCE_ADDRESS_IPV4 1
|
||||
#define PCE_ADDRESS_IPV6 2
|
||||
uint16_t reserved;
|
||||
struct in_addr value; /* PCE address */
|
||||
} address;
|
||||
@ -118,6 +118,7 @@ struct ri_pce_subtlv_address {
|
||||
|
||||
/* PCE Path-Scope Sub-TLV */ /* Mandatory */
|
||||
#define RI_PCE_SUBTLV_PATH_SCOPE 2
|
||||
#define RI_PCE_SUBTLV_PATH_SCOPE_SIZE 4
|
||||
struct ri_pce_subtlv_path_scope {
|
||||
struct tlv_header header; /* Type = 2; Length = 4 bytes. */
|
||||
/*
|
||||
@ -128,11 +129,11 @@ struct ri_pce_subtlv_path_scope {
|
||||
};
|
||||
|
||||
/* PCE Domain Sub-TLV */ /* Optional */
|
||||
#define RI_PCE_SUBTLV_DOMAIN 3
|
||||
|
||||
#define PCE_DOMAIN_TYPE_AREA 1
|
||||
#define PCE_DOMAIN_TYPE_AS 2
|
||||
#define PCE_DOMAIN_TYPE_AS 2
|
||||
|
||||
#define RI_PCE_SUBTLV_DOMAIN 3
|
||||
#define RI_PCE_SUBTLV_DOMAIN_SIZE 8
|
||||
struct ri_pce_subtlv_domain {
|
||||
struct tlv_header header; /* Type = 3; Length = 8 bytes. */
|
||||
uint16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
|
||||
@ -142,6 +143,7 @@ struct ri_pce_subtlv_domain {
|
||||
|
||||
/* PCE Neighbor Sub-TLV */ /* Mandatory if R or S bit is set */
|
||||
#define RI_PCE_SUBTLV_NEIGHBOR 4
|
||||
#define RI_PCE_SUBTLV_NEIGHBOR_SIZE 8
|
||||
struct ri_pce_subtlv_neighbor {
|
||||
struct tlv_header header; /* Type = 4; Length = 8 bytes. */
|
||||
uint16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
|
||||
@ -151,6 +153,7 @@ struct ri_pce_subtlv_neighbor {
|
||||
|
||||
/* PCE Capabilities Flags Sub-TLV */ /* Optional */
|
||||
#define RI_PCE_SUBTLV_CAP_FLAG 5
|
||||
#define RI_PCE_SUBTLV_CAP_FLAG_SIZE 4
|
||||
|
||||
#define PCE_CAP_GMPLS_LINK 0x0001
|
||||
#define PCE_CAP_BIDIRECTIONAL 0x0002
|
||||
|
@ -954,7 +954,7 @@ static inline void update_adj_sid(struct sr_nhlfe n1, struct sr_nhlfe n2)
|
||||
*/
|
||||
|
||||
/* Extended Link SubTLVs Getter */
|
||||
static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
|
||||
static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh, size_t size)
|
||||
{
|
||||
|
||||
struct sr_link *srl;
|
||||
@ -966,13 +966,20 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
|
||||
struct tlv_header *sub_tlvh;
|
||||
uint16_t length = 0, sum = 0, i = 0;
|
||||
|
||||
/* Check TLV size */
|
||||
if ((ntohs(tlvh->length) > size)
|
||||
|| ntohs(tlvh->length) < EXT_TLV_LINK_SIZE) {
|
||||
zlog_warn("Wrong Extended Link TLV size. Abort!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(tlvh->length) - EXT_TLV_LINK_SIZE;
|
||||
sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
|
||||
+ EXT_TLV_LINK_SIZE);
|
||||
for (; sum < length; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
|
||||
for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
|
||||
switch (ntohs(sub_tlvh->type)) {
|
||||
case EXT_SUBTLV_ADJ_SID:
|
||||
adj_sid = (struct ext_subtlv_adj_sid *)sub_tlvh;
|
||||
@ -1025,7 +1032,8 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
|
||||
}
|
||||
|
||||
/* Extended Prefix SubTLVs Getter */
|
||||
static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
|
||||
static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh,
|
||||
size_t size)
|
||||
{
|
||||
|
||||
struct sr_prefix *srp;
|
||||
@ -1035,13 +1043,20 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
|
||||
struct tlv_header *sub_tlvh;
|
||||
uint16_t length = 0, sum = 0;
|
||||
|
||||
/* Check TLV size */
|
||||
if ((ntohs(tlvh->length) > size)
|
||||
|| ntohs(tlvh->length) < EXT_TLV_PREFIX_SIZE) {
|
||||
zlog_warn("Wrong Extended Link TLV size. Abort!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(tlvh->length) - EXT_TLV_PREFIX_SIZE;
|
||||
sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
|
||||
+ EXT_TLV_PREFIX_SIZE);
|
||||
for (; sum < length; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
|
||||
for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
|
||||
switch (ntohs(sub_tlvh->type)) {
|
||||
case EXT_SUBTLV_PREFIX_SID:
|
||||
psid = (struct ext_subtlv_prefix_sid *)sub_tlvh;
|
||||
@ -1353,7 +1368,7 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
|
||||
|
||||
/* Collect Router Information Sub TLVs */
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
srgb.range_size = 0;
|
||||
srgb.lower_bound = 0;
|
||||
|
||||
@ -1362,24 +1377,20 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
|
||||
switch (ntohs(tlvh->type)) {
|
||||
case RI_SR_TLV_SR_ALGORITHM:
|
||||
algo = (struct ri_sr_tlv_sr_algorithm *)tlvh;
|
||||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
case RI_SR_TLV_SRGB_LABEL_RANGE:
|
||||
ri_srgb = (struct ri_sr_tlv_sid_label_range *)tlvh;
|
||||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
case RI_SR_TLV_SRLB_LABEL_RANGE:
|
||||
ri_srlb = (struct ri_sr_tlv_sid_label_range *)tlvh;
|
||||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
case RI_SR_TLV_NODE_MSD:
|
||||
msd = ((struct ri_sr_tlv_node_msd *)(tlvh))->value;
|
||||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
}
|
||||
sum += TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
/* Check if Segment Routing Capabilities has been found */
|
||||
@ -1519,7 +1530,7 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa)
|
||||
struct lsa_header *lsah = lsa->data;
|
||||
struct sr_link *srl;
|
||||
|
||||
uint16_t length, sum;
|
||||
int length;
|
||||
|
||||
osr_debug("SR (%s): Process Extended Link LSA 8.0.0.%u from %pI4",
|
||||
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
|
||||
@ -1546,20 +1557,19 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa)
|
||||
}
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
sum = 0;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); (sum < length) && (tlvh != NULL);
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); length > 0 && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
if (ntohs(tlvh->type) == EXT_TLV_LINK) {
|
||||
/* Got Extended Link information */
|
||||
srl = get_ext_link_sid(tlvh);
|
||||
srl = get_ext_link_sid(tlvh, length);
|
||||
/* Update SID if not null */
|
||||
if (srl != NULL) {
|
||||
srl->instance = ntohl(lsah->id.s_addr);
|
||||
update_ext_link_sid(srn, srl, lsa->flags);
|
||||
}
|
||||
}
|
||||
sum += TLV_SIZE(tlvh);
|
||||
length -= TLV_SIZE(tlvh);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1753,7 +1763,7 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
|
||||
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
|
||||
struct sr_prefix *srp;
|
||||
|
||||
uint16_t length, sum;
|
||||
int length;
|
||||
|
||||
osr_debug("SR (%s): Process Extended Prefix LSA 7.0.0.%u from %pI4",
|
||||
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
|
||||
@ -1780,20 +1790,19 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
|
||||
}
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
sum = 0;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); length > 0 && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
if (ntohs(tlvh->type) == EXT_TLV_LINK) {
|
||||
/* Got Extended Link information */
|
||||
srp = get_ext_prefix_sid(tlvh);
|
||||
srp = get_ext_prefix_sid(tlvh, length);
|
||||
/* Update SID if not null */
|
||||
if (srp != NULL) {
|
||||
srp->instance = ntohl(lsah->id.s_addr);
|
||||
update_ext_prefix_sid(srn, srp);
|
||||
}
|
||||
}
|
||||
sum += TLV_SIZE(tlvh);
|
||||
length -= TLV_SIZE(tlvh);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ struct ri_sr_tlv_sr_algorithm {
|
||||
/* RI SID/Label Range TLV used for SRGB & SRLB - section 3.2 & 3.3 */
|
||||
#define RI_SR_TLV_SRGB_LABEL_RANGE 9
|
||||
#define RI_SR_TLV_SRLB_LABEL_RANGE 14
|
||||
#define RI_SR_TLV_LABEL_RANGE_SIZE 12
|
||||
struct ri_sr_tlv_sid_label_range {
|
||||
struct tlv_header header;
|
||||
/* Only 24 upper most bits are significant */
|
||||
@ -99,6 +100,7 @@ struct ri_sr_tlv_sid_label_range {
|
||||
|
||||
/* RI Node/MSD TLV as per RFC 8476 */
|
||||
#define RI_SR_TLV_NODE_MSD 12
|
||||
#define RI_SR_TLV_NODE_MSD_SIZE 4
|
||||
struct ri_sr_tlv_node_msd {
|
||||
struct tlv_header header;
|
||||
uint8_t subtype; /* always = 1 */
|
||||
|
167
ospfd/ospf_te.c
167
ospfd/ospf_te.c
@ -1882,7 +1882,7 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
|
||||
struct ls_edge *edge;
|
||||
struct ls_subnet *subnet;
|
||||
struct listnode *node;
|
||||
int len;
|
||||
int len, links;
|
||||
|
||||
/* Sanity Check */
|
||||
if (!ted || !lsa || !lsa->data)
|
||||
@ -1932,8 +1932,9 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
|
||||
subnet->status = ORPHAN;
|
||||
|
||||
/* Then, process Link Information */
|
||||
len = ntohs(rl->header.length) - 4;
|
||||
for (int i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) {
|
||||
len = lsa->size - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE;
|
||||
links = ntohs(rl->links);
|
||||
for (int i = 0; i < links && len > 0; len -= 12, i++) {
|
||||
struct prefix p;
|
||||
uint32_t metric;
|
||||
|
||||
@ -2152,20 +2153,20 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
tlvh = TLV_HDR_TOP(lsa->data);
|
||||
len = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
uint32_t total_len = TLV_BODY_SIZE(lsa->data) - OSPF_LSA_HEADER_SIZE;
|
||||
/* Check if TE Router-ID TLV is present */
|
||||
if (ntohs(tlvh->type) == TE_TLV_ROUTER_ADDR) {
|
||||
/* if TE Router-ID is alone, we are done ... */
|
||||
if (len == TE_LINK_SUBTLV_DEF_SIZE)
|
||||
return 0;
|
||||
|
||||
/* If TE Router-ID is only TLV we are done */
|
||||
if (ntohs(tlvh->type) == TE_TLV_ROUTER_ADDR
|
||||
&& total_len == sizeof(struct te_tlv_router_addr))
|
||||
return 0;
|
||||
|
||||
/* Skip TE Router-ID if present */
|
||||
if (ntohs(tlvh->type) == TE_TLV_ROUTER_ADDR)
|
||||
/* ... otherwise, skip it */
|
||||
len -= TE_LINK_SUBTLV_DEF_SIZE + TLV_HDR_SIZE;
|
||||
tlvh = TLV_HDR_NEXT(tlvh);
|
||||
}
|
||||
|
||||
/* Check if we have a TE Link TLV */
|
||||
len = TLV_BODY_SIZE(tlvh);
|
||||
/* Check if we have a valid TE Link TLV */
|
||||
if ((len == 0) || (ntohs(tlvh->type) != TE_TLV_LINK))
|
||||
return 0;
|
||||
|
||||
@ -2467,8 +2468,9 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa)
|
||||
&lsa->data->id, &node->router_id);
|
||||
|
||||
/* Initialize TLV browsing */
|
||||
len = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
len = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < len && tlvh;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
struct ri_sr_tlv_sr_algorithm *algo;
|
||||
struct ri_sr_tlv_sid_label_range *range;
|
||||
struct ri_sr_tlv_node_msd *msd;
|
||||
@ -3152,11 +3154,25 @@ static void ospf_te_init_ted(struct ls_ted *ted, struct ospf *ospf)
|
||||
/*------------------------------------------------------------------------*
|
||||
* Followings are vty session control functions.
|
||||
*------------------------------------------------------------------------*/
|
||||
#define check_tlv_size(size, msg) \
|
||||
do { \
|
||||
if (ntohs(tlvh->length) > size) { \
|
||||
if (vty != NULL) \
|
||||
vty_out(vty, " Wrong %s TLV size: %d(%d)\n", \
|
||||
msg, ntohs(tlvh->length), size); \
|
||||
else \
|
||||
zlog_debug(" Wrong %s TLV size: %d(%d)\n", \
|
||||
msg, ntohs(tlvh->length), size); \
|
||||
return size + TLV_HDR_SIZE; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
|
||||
{
|
||||
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);
|
||||
else
|
||||
@ -3165,10 +3181,23 @@ static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
static uint16_t show_vty_link_header(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)
|
||||
{
|
||||
struct te_tlv_link *top = (struct te_tlv_link *)tlvh;
|
||||
|
||||
if (TLV_SIZE(tlvh) > buf_size) {
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
else
|
||||
zlog_debug(
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Link: %u octets of data\n",
|
||||
ntohs(top->header.length));
|
||||
@ -3185,6 +3214,8 @@ static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
|
||||
struct te_link_subtlv_link_type *top;
|
||||
const char *cp = "Unknown";
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_TYPE_SIZE, "Link Type");
|
||||
|
||||
top = (struct te_link_subtlv_link_type *)tlvh;
|
||||
switch (top->link_type.value) {
|
||||
case LINK_TYPE_SUBTLV_VALUE_PTP:
|
||||
@ -3211,6 +3242,8 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_link_id *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Link ID");
|
||||
|
||||
top = (struct te_link_subtlv_link_id *)tlvh;
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Link-ID: %pI4\n", &top->value);
|
||||
@ -3221,11 +3254,24 @@ 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)
|
||||
struct tlv_header *tlvh,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct te_link_subtlv_lclif_ipaddr *top;
|
||||
int i, n;
|
||||
|
||||
if (TLV_SIZE(tlvh) > buf_size) {
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
else
|
||||
zlog_debug(
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
top = (struct te_link_subtlv_lclif_ipaddr *)tlvh;
|
||||
n = ntohs(tlvh->length) / sizeof(top->value[0]);
|
||||
|
||||
@ -3244,11 +3290,24 @@ 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)
|
||||
struct tlv_header *tlvh,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct te_link_subtlv_rmtif_ipaddr *top;
|
||||
int i, n;
|
||||
|
||||
if (TLV_SIZE(tlvh) > buf_size) {
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
else
|
||||
zlog_debug(
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
top = (struct te_link_subtlv_rmtif_ipaddr *)tlvh;
|
||||
n = ntohs(tlvh->length) / sizeof(top->value[0]);
|
||||
if (vty != NULL)
|
||||
@ -3270,6 +3329,8 @@ static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_te_metric *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "TE Metric");
|
||||
|
||||
top = (struct te_link_subtlv_te_metric *)tlvh;
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Traffic Engineering Metric: %u\n",
|
||||
@ -3287,6 +3348,8 @@ static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
|
||||
struct te_link_subtlv_max_bw *top;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Maximum Bandwidth");
|
||||
|
||||
top = (struct te_link_subtlv_max_bw *)tlvh;
|
||||
fval = ntohf(top->value);
|
||||
|
||||
@ -3304,6 +3367,8 @@ static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
|
||||
struct te_link_subtlv_max_rsv_bw *top;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Maximum Reservable Bandwidth");
|
||||
|
||||
top = (struct te_link_subtlv_max_rsv_bw *)tlvh;
|
||||
fval = ntohf(top->value);
|
||||
|
||||
@ -3324,6 +3389,8 @@ static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
|
||||
float fval1, fval2;
|
||||
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,
|
||||
@ -3353,6 +3420,8 @@ static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_rsc_clsclr *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Resource class/color");
|
||||
|
||||
top = (struct te_link_subtlv_rsc_clsclr *)tlvh;
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Resource class/color: 0x%x\n",
|
||||
@ -3369,6 +3438,8 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_lrrid *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_LRRID_SIZE, "Local/Remote Router ID");
|
||||
|
||||
top = (struct te_link_subtlv_lrrid *)tlvh;
|
||||
|
||||
if (vty != NULL) {
|
||||
@ -3391,6 +3462,8 @@ static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_llri *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_LLRI_SIZE, "Link Local/Remote ID");
|
||||
|
||||
top = (struct te_link_subtlv_llri *)tlvh;
|
||||
|
||||
if (vty != NULL) {
|
||||
@ -3413,6 +3486,8 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_rip *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Remote ASBR Address");
|
||||
|
||||
top = (struct te_link_subtlv_rip *)tlvh;
|
||||
|
||||
if (vty != NULL)
|
||||
@ -3430,6 +3505,8 @@ static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
|
||||
{
|
||||
struct te_link_subtlv_ras *top;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Remote AS number");
|
||||
|
||||
top = (struct te_link_subtlv_ras *)tlvh;
|
||||
|
||||
if (vty != NULL)
|
||||
@ -3449,6 +3526,8 @@ static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
|
||||
uint32_t delay;
|
||||
uint32_t anomalous;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Average Link Delay");
|
||||
|
||||
top = (struct te_link_subtlv_av_delay *)tlvh;
|
||||
delay = (uint32_t)ntohl(top->value) & TE_EXT_MASK;
|
||||
anomalous = (uint32_t)ntohl(top->value) & TE_EXT_ANORMAL;
|
||||
@ -3470,6 +3549,8 @@ static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
|
||||
uint32_t low, high;
|
||||
uint32_t anomalous;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_MM_DELAY_SIZE, "Min/Max Link Delay");
|
||||
|
||||
top = (struct te_link_subtlv_mm_delay *)tlvh;
|
||||
low = (uint32_t)ntohl(top->low) & TE_EXT_MASK;
|
||||
anomalous = (uint32_t)ntohl(top->low) & TE_EXT_ANORMAL;
|
||||
@ -3491,6 +3572,8 @@ static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
|
||||
struct te_link_subtlv_delay_var *top;
|
||||
uint32_t jitter;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Link Delay Variation");
|
||||
|
||||
top = (struct te_link_subtlv_delay_var *)tlvh;
|
||||
jitter = (uint32_t)ntohl(top->value) & TE_EXT_MASK;
|
||||
|
||||
@ -3510,6 +3593,8 @@ static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
|
||||
uint32_t anomalous;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Link Loss");
|
||||
|
||||
top = (struct te_link_subtlv_pkt_loss *)tlvh;
|
||||
loss = (uint32_t)ntohl(top->value) & TE_EXT_MASK;
|
||||
fval = (float)(loss * LOSS_PRECISION);
|
||||
@ -3531,6 +3616,8 @@ static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
|
||||
struct te_link_subtlv_res_bw *top;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Residual Bandwidth");
|
||||
|
||||
top = (struct te_link_subtlv_res_bw *)tlvh;
|
||||
fval = ntohf(top->value);
|
||||
|
||||
@ -3552,6 +3639,8 @@ static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
|
||||
struct te_link_subtlv_ava_bw *top;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Available Bandwidth");
|
||||
|
||||
top = (struct te_link_subtlv_ava_bw *)tlvh;
|
||||
fval = ntohf(top->value);
|
||||
|
||||
@ -3573,6 +3662,8 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
|
||||
struct te_link_subtlv_use_bw *top;
|
||||
float fval;
|
||||
|
||||
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Utilized Bandwidth");
|
||||
|
||||
top = (struct te_link_subtlv_use_bw *)tlvh;
|
||||
fval = ntohf(top->value);
|
||||
|
||||
@ -3588,8 +3679,21 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
|
||||
return TLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (TLV_SIZE(tlvh) > buf_size) {
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
else
|
||||
zlog_debug(
|
||||
" TLV size %d exceeds buffer size. Abort!",
|
||||
TLV_SIZE(tlvh));
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
||||
ntohs(tlvh->type), ntohs(tlvh->length));
|
||||
@ -3607,8 +3711,7 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
|
||||
struct tlv_header *tlvh;
|
||||
uint16_t sum = subtotal;
|
||||
|
||||
for (tlvh = tlvh0; sum < total;
|
||||
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||
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);
|
||||
@ -3617,10 +3720,12 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
|
||||
sum += show_vty_link_subtlv_link_id(vty, tlvh);
|
||||
break;
|
||||
case TE_LINK_SUBTLV_LCLIF_IPADDR:
|
||||
sum += show_vty_link_subtlv_lclif_ipaddr(vty, tlvh);
|
||||
sum += show_vty_link_subtlv_lclif_ipaddr(vty, tlvh,
|
||||
total - sum);
|
||||
break;
|
||||
case TE_LINK_SUBTLV_RMTIF_IPADDR:
|
||||
sum += show_vty_link_subtlv_rmtif_ipaddr(vty, tlvh);
|
||||
sum += show_vty_link_subtlv_rmtif_ipaddr(vty, tlvh,
|
||||
total - sum);
|
||||
break;
|
||||
case TE_LINK_SUBTLV_TE_METRIC:
|
||||
sum += show_vty_link_subtlv_te_metric(vty, tlvh);
|
||||
@ -3671,7 +3776,7 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
|
||||
sum += show_vty_link_subtlv_use_bw(vty, tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3687,9 +3792,9 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
uint16_t subtotal, uint16_t total) = NULL;
|
||||
|
||||
sum = 0;
|
||||
total = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||
total = lsa->size - OSPF_LSA_HEADER_SIZE;
|
||||
|
||||
for (tlvh = TLV_HDR_TOP(lsah); sum < total;
|
||||
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);
|
||||
@ -3704,12 +3809,12 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||
sum += show_vty_router_addr(vty, tlvh);
|
||||
break;
|
||||
case TE_TLV_LINK:
|
||||
sum += show_vty_link_header(vty, tlvh);
|
||||
sum += show_vty_link_header(vty, tlvh, total - sum);
|
||||
subfunc = ospf_mpls_te_show_link_subtlv;
|
||||
next = TLV_DATA(tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4081,10 +4186,12 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
|
||||
show_vty_link_subtlv_link_id(vty, &lp->link_id.header);
|
||||
if (TLV_TYPE(lp->lclif_ipaddr) != 0)
|
||||
show_vty_link_subtlv_lclif_ipaddr(
|
||||
vty, &lp->lclif_ipaddr.header);
|
||||
vty, &lp->lclif_ipaddr.header,
|
||||
lp->lclif_ipaddr.header.length);
|
||||
if (TLV_TYPE(lp->rmtif_ipaddr) != 0)
|
||||
show_vty_link_subtlv_rmtif_ipaddr(
|
||||
vty, &lp->rmtif_ipaddr.header);
|
||||
vty, &lp->rmtif_ipaddr.header,
|
||||
lp->rmtif_ipaddr.header.length);
|
||||
if (TLV_TYPE(lp->rip) != 0)
|
||||
show_vty_link_subtlv_rip(vty, &lp->rip.header);
|
||||
if (TLV_TYPE(lp->ras) != 0)
|
||||
|
@ -6400,6 +6400,7 @@ static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
||||
|
||||
if (lsa != NULL) {
|
||||
struct network_lsa *nl = (struct network_lsa *)lsa->data;
|
||||
struct in_addr *addr;
|
||||
|
||||
show_ip_ospf_database_header(vty, lsa, json);
|
||||
|
||||
@ -6410,24 +6411,25 @@ static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
||||
json_object_int_add(json, "networkMask",
|
||||
ip_masklen(nl->mask));
|
||||
|
||||
length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4;
|
||||
|
||||
for (i = 0; length > 0; i++, length -= 4)
|
||||
length = lsa->size - OSPF_LSA_HEADER_SIZE - 4;
|
||||
addr = &nl->routers[0];
|
||||
for (i = 0; length > 0 && addr;
|
||||
length -= 4, addr = &nl->routers[++i])
|
||||
if (!json) {
|
||||
vty_out(vty, " Attached Router: %pI4\n",
|
||||
&nl->routers[i]);
|
||||
addr);
|
||||
vty_out(vty, "\n");
|
||||
} else {
|
||||
json_router = json_object_new_object();
|
||||
json_object_string_add(
|
||||
json_router, "attachedRouterId",
|
||||
inet_ntop(AF_INET, &nl->routers[i],
|
||||
buf, sizeof(buf)));
|
||||
json_object_object_add(
|
||||
json_attached_rt,
|
||||
inet_ntop(AF_INET, &(nl->routers[i]),
|
||||
buf, sizeof(buf)),
|
||||
json_router);
|
||||
inet_ntop(AF_INET, addr, buf,
|
||||
sizeof(buf)));
|
||||
json_object_object_add(json_attached_rt,
|
||||
inet_ntop(AF_INET, addr,
|
||||
buf,
|
||||
sizeof(buf)),
|
||||
json_router);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user