mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 16:17:38 +00:00
Merge pull request #10517 from idryzhov/isis_router_cap_tlv_fixes
isisd: fix router capability TLV parsing issues
This commit is contained in:
commit
107f77b56f
@ -3007,28 +3007,55 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
|
|||||||
|
|
||||||
type = stream_getc(s);
|
type = stream_getc(s);
|
||||||
length = stream_getc(s);
|
length = stream_getc(s);
|
||||||
|
|
||||||
|
if (length > STREAM_READABLE(s) || length > subtlv_len - 2) {
|
||||||
|
sbuf_push(
|
||||||
|
log, indent,
|
||||||
|
"WARNING: Router Capability subTLV length too large compared to expected size\n");
|
||||||
|
stream_forward_getp(s, STREAM_READABLE(s));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ISIS_SUBTLV_SID_LABEL_RANGE:
|
case ISIS_SUBTLV_SID_LABEL_RANGE:
|
||||||
/* Check that SRGB is correctly formated */
|
/* Check that SRGB is correctly formated */
|
||||||
if (length < SUBTLV_RANGE_LABEL_SIZE
|
if (length < SUBTLV_RANGE_LABEL_SIZE
|
||||||
|| length > SUBTLV_RANGE_INDEX_SIZE) {
|
|| length > SUBTLV_RANGE_INDEX_SIZE) {
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, length);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
/* Only one SRGB is supported. Skip subsequent one */
|
/* Only one SRGB is supported. Skip subsequent one */
|
||||||
if (rcap->srgb.range_size != 0) {
|
if (rcap->srgb.range_size != 0) {
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, length);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
rcap->srgb.flags = stream_getc(s);
|
rcap->srgb.flags = stream_getc(s);
|
||||||
rcap->srgb.range_size = stream_get3(s);
|
rcap->srgb.range_size = stream_get3(s);
|
||||||
/* Skip Type and get Length of SID Label */
|
/* Skip Type and get Length of SID Label */
|
||||||
stream_getc(s);
|
stream_getc(s);
|
||||||
size = stream_getc(s);
|
size = stream_getc(s);
|
||||||
if (size == ISIS_SUBTLV_SID_LABEL_SIZE)
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_LABEL_SIZE
|
||||||
|
&& length != SUBTLV_RANGE_LABEL_SIZE) {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_INDEX_SIZE
|
||||||
|
&& length != SUBTLV_RANGE_INDEX_SIZE) {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_LABEL_SIZE) {
|
||||||
rcap->srgb.lower_bound = stream_get3(s);
|
rcap->srgb.lower_bound = stream_get3(s);
|
||||||
else
|
} else if (size == ISIS_SUBTLV_SID_INDEX_SIZE) {
|
||||||
rcap->srgb.lower_bound = stream_getl(s);
|
rcap->srgb.lower_bound = stream_getl(s);
|
||||||
|
} else {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* SRGB sanity checks. */
|
/* SRGB sanity checks. */
|
||||||
if (rcap->srgb.range_size == 0
|
if (rcap->srgb.range_size == 0
|
||||||
@ -3042,9 +3069,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
|
|||||||
/* Only one range is supported. Skip subsequent one */
|
/* Only one range is supported. Skip subsequent one */
|
||||||
size = length - (size + SUBTLV_SR_BLOCK_SIZE);
|
size = length - (size + SUBTLV_SR_BLOCK_SIZE);
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ISIS_SUBTLV_ALGORITHM:
|
case ISIS_SUBTLV_ALGORITHM:
|
||||||
|
if (length == 0)
|
||||||
|
break;
|
||||||
/* Only 2 algorithms are supported: SPF & Strict SPF */
|
/* Only 2 algorithms are supported: SPF & Strict SPF */
|
||||||
stream_get(&rcap->algo, s,
|
stream_get(&rcap->algo, s,
|
||||||
length > SR_ALGORITHM_COUNT
|
length > SR_ALGORITHM_COUNT
|
||||||
@ -3059,12 +3089,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
|
|||||||
if (length < SUBTLV_RANGE_LABEL_SIZE
|
if (length < SUBTLV_RANGE_LABEL_SIZE
|
||||||
|| length > SUBTLV_RANGE_INDEX_SIZE) {
|
|| length > SUBTLV_RANGE_INDEX_SIZE) {
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, length);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
/* RFC 8667 section #3.3: Only one SRLB is authorized */
|
/* RFC 8667 section #3.3: Only one SRLB is authorized */
|
||||||
if (rcap->srlb.range_size != 0) {
|
if (rcap->srlb.range_size != 0) {
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, length);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
/* Ignore Flags which are not defined */
|
/* Ignore Flags which are not defined */
|
||||||
stream_getc(s);
|
stream_getc(s);
|
||||||
@ -3072,10 +3102,27 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
|
|||||||
/* Skip Type and get Length of SID Label */
|
/* Skip Type and get Length of SID Label */
|
||||||
stream_getc(s);
|
stream_getc(s);
|
||||||
size = stream_getc(s);
|
size = stream_getc(s);
|
||||||
if (size == ISIS_SUBTLV_SID_LABEL_SIZE)
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_LABEL_SIZE
|
||||||
|
&& length != SUBTLV_RANGE_LABEL_SIZE) {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_INDEX_SIZE
|
||||||
|
&& length != SUBTLV_RANGE_INDEX_SIZE) {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == ISIS_SUBTLV_SID_LABEL_SIZE) {
|
||||||
rcap->srlb.lower_bound = stream_get3(s);
|
rcap->srlb.lower_bound = stream_get3(s);
|
||||||
else
|
} else if (size == ISIS_SUBTLV_SID_INDEX_SIZE) {
|
||||||
rcap->srlb.lower_bound = stream_getl(s);
|
rcap->srlb.lower_bound = stream_getl(s);
|
||||||
|
} else {
|
||||||
|
stream_forward_getp(s, length - 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* SRLB sanity checks. */
|
/* SRLB sanity checks. */
|
||||||
if (rcap->srlb.range_size == 0
|
if (rcap->srlb.range_size == 0
|
||||||
@ -3089,13 +3136,14 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
|
|||||||
/* Only one range is supported. Skip subsequent one */
|
/* Only one range is supported. Skip subsequent one */
|
||||||
size = length - (size + SUBTLV_SR_BLOCK_SIZE);
|
size = length - (size + SUBTLV_SR_BLOCK_SIZE);
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ISIS_SUBTLV_NODE_MSD:
|
case ISIS_SUBTLV_NODE_MSD:
|
||||||
/* Check that MSD is correctly formated */
|
/* Check that MSD is correctly formated */
|
||||||
if (length < MSD_TLV_SIZE) {
|
if (length < MSD_TLV_SIZE) {
|
||||||
stream_forward_getp(s, length);
|
stream_forward_getp(s, length);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
msd_type = stream_getc(s);
|
msd_type = stream_getc(s);
|
||||||
rcap->msd = stream_getc(s);
|
rcap->msd = stream_getc(s);
|
||||||
|
@ -447,6 +447,7 @@ enum ext_subtlv_size {
|
|||||||
|
|
||||||
/* RFC 8667 sections #2 & #3 */
|
/* RFC 8667 sections #2 & #3 */
|
||||||
ISIS_SUBTLV_SID_LABEL_SIZE = 3,
|
ISIS_SUBTLV_SID_LABEL_SIZE = 3,
|
||||||
|
ISIS_SUBTLV_SID_INDEX_SIZE = 4,
|
||||||
ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
|
ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
|
||||||
ISIS_SUBTLV_ALGORITHM_SIZE = 4,
|
ISIS_SUBTLV_ALGORITHM_SIZE = 4,
|
||||||
ISIS_SUBTLV_ADJ_SID_SIZE = 5,
|
ISIS_SUBTLV_ADJ_SID_SIZE = 5,
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user