diff options
-rw-r--r-- | isisd/isis_tlvs.c | 38 | ||||
-rw-r--r-- | isisd/isis_tlvs.h | 7 |
2 files changed, 39 insertions, 6 deletions
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a58038b32..f3c9c4769 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -2744,7 +2744,7 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, uint8_t type; uint8_t length; uint8_t subtlv_len; - uint8_t sid_len; + uint8_t size; sbuf_push(log, indent, "Unpacking Router Capability TLV...\n"); if (tlv_len < ISIS_ROUTER_CAP_SIZE) { @@ -2778,6 +2778,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, length = stream_getc(s); switch (type) { case ISIS_SUBTLV_SID_LABEL_RANGE: + /* Check that SRGB is correctly formated */ + if (length < SUBTLV_RANGE_LABEL_SIZE + || length > SUBTLV_RANGE_INDEX_SIZE) { + stream_forward_getp(s, length); + continue; + } /* Only one SRGB is supported. Skip subsequent one */ if (rcap->srgb.range_size != 0) { stream_forward_getp(s, length); @@ -2787,8 +2793,8 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, rcap->srgb.range_size = stream_get3(s); /* Skip Type and get Length of SID Label */ stream_getc(s); - sid_len = stream_getc(s); - if (sid_len == ISIS_SUBTLV_SID_LABEL_SIZE) + size = stream_getc(s); + if (size == ISIS_SUBTLV_SID_LABEL_SIZE) rcap->srgb.lower_bound = stream_get3(s); else rcap->srgb.lower_bound = stream_getl(s); @@ -2802,6 +2808,10 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, rcap->srgb.lower_bound = 0; rcap->srgb.range_size = 0; } + /* Only one range is supported. Skip subsequent one */ + size = length - (size + SUBTLV_SR_BLOCK_SIZE); + if (size > 0) + stream_forward_getp(s, length); break; case ISIS_SUBTLV_ALGORITHM: /* Only 2 algorithms are supported: SPF & Strict SPF */ @@ -2814,6 +2824,12 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, s, length - SR_ALGORITHM_COUNT); break; case ISIS_SUBTLV_SRLB: + /* Check that SRLB is correctly formated */ + if (length < SUBTLV_RANGE_LABEL_SIZE + || length > SUBTLV_RANGE_INDEX_SIZE) { + stream_forward_getp(s, length); + continue; + } /* RFC 8667 section #3.3: Only one SRLB is authorized */ if (rcap->srlb.range_size != 0) { stream_forward_getp(s, length); @@ -2824,8 +2840,8 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, rcap->srlb.range_size = stream_get3(s); /* Skip Type and get Length of SID Label */ stream_getc(s); - sid_len = stream_getc(s); - if (sid_len == ISIS_SUBTLV_SID_LABEL_SIZE) + size = stream_getc(s); + if (size == ISIS_SUBTLV_SID_LABEL_SIZE) rcap->srlb.lower_bound = stream_get3(s); else rcap->srlb.lower_bound = stream_getl(s); @@ -2839,13 +2855,25 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, rcap->srlb.lower_bound = 0; rcap->srlb.range_size = 0; } + /* Only one range is supported. Skip subsequent one */ + size = length - (size + SUBTLV_SR_BLOCK_SIZE); + if (size > 0) + stream_forward_getp(s, length); break; case ISIS_SUBTLV_NODE_MSD: + /* Check that MSD is correctly formated */ + if (length < MSD_TLV_SIZE) { + stream_forward_getp(s, length); + continue; + } msd_type = stream_getc(s); rcap->msd = stream_getc(s); /* Only BMI-MSD type has been defined in RFC 8491 */ if (msd_type != MSD_TYPE_BASE_MPLS_IMPOSITION) rcap->msd = 0; + /* Only one MSD is standardized. Skip others */ + if (length > MSD_TLV_SIZE) + stream_forward_getp(s, length - MSD_TLV_SIZE); break; default: stream_forward_getp(s, length); diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 0cf49b526..1c0d97f2c 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -140,6 +140,9 @@ struct isis_threeway_adj { #define ISIS_SUBTLV_SRGB_FLAG_V 0x40 #define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I) #define IS_SR_IPV6(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V) +#define SUBTLV_SR_BLOCK_SIZE 6 +#define SUBTLV_RANGE_INDEX_SIZE 10 +#define SUBTLV_RANGE_LABEL_SIZE 9 /* Structure aggregating SR Global (SRGB) or Local (SRLB) Block info */ struct isis_sr_block { @@ -209,6 +212,9 @@ struct isis_lan_adj_sid { #define SR_ALGORITHM_STRICT_SPF 1 #define SR_ALGORITHM_UNSET 255 +#define MSD_TYPE_BASE_MPLS_IMPOSITION 0x01 +#define MSD_TLV_SIZE 2 + struct isis_router_cap { struct in_addr router_id; uint8_t flags; @@ -218,7 +224,6 @@ struct isis_router_cap { struct isis_sr_block srlb; uint8_t algo[SR_ALGORITHM_COUNT]; /* RFC 8491 */ -#define MSD_TYPE_BASE_MPLS_IMPOSITION 0x01 uint8_t msd; }; |