Merge pull request #8408 from Orange-OpenSource/TE

ospfd: Correct Coverity defects
This commit is contained in:
Igor Ryzhov 2021-05-19 17:04:48 +03:00 committed by GitHub
commit 1f25f6c768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 465 additions and 204 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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--;
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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))
/*

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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)

View File

@ -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);
}
}