summaryrefslogtreecommitdiff
path: root/isisd
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2017-01-31 16:10:25 +0100
committerChristian Franke <chris@opensourcerouting.org>2017-01-31 16:13:23 +0100
commit0de64cbbd3413038818586af733b115cddca6b83 (patch)
tree6b3e6d4f087113a4ae683caf662b1c168893aa6d /isisd
parente08f1a05f248cf8cd25cde5f1af36bbdd6cbfb9b (diff)
isisd: parse TE-IP reachability and IPv6 reachability subtlvs
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'isisd')
-rw-r--r--isisd/isis_tlv.c56
-rw-r--r--isisd/isis_tlv.h2
2 files changed, 51 insertions, 7 deletions
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index 1d29d78287..b19a181a3f 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -614,12 +614,32 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
if (!tlvs->te_ipv4_reachs)
tlvs->te_ipv4_reachs = list_new ();
listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach);
- /* this trickery is permitable since no subtlvs are defined */
- value_len += 5 + ((te_ipv4_reach->control & 0x3F) ?
- ((((te_ipv4_reach->control & 0x3F) -
- 1) >> 3) + 1) : 0);
- pnt += 5 + ((te_ipv4_reach->control & 0x3F) ?
- ((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0);
+
+ /* Metric + Control-Byte + Prefix */
+ unsigned int entry_len = 5 + PSIZE(te_ipv4_reach->control & 0x3F);
+ value_len += entry_len;
+ pnt += entry_len;
+
+ if (te_ipv4_reach->control & TE_IPV4_HAS_SUBTLV)
+ {
+ if (length <= value_len)
+ {
+ zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLV missing",
+ areatag);
+ retval = ISIS_WARNING;
+ break;
+ }
+ u_char subtlv_len = *pnt;
+ value_len += subtlv_len + 1;
+ pnt += subtlv_len + 1;
+ if (length < value_len)
+ {
+ zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLVs have oversize",
+ areatag);
+ retval = ISIS_WARNING;
+ break;
+ }
+ }
}
}
@@ -687,6 +707,27 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
prefix_octets = ((ipv6_reach->prefix_len + 7) / 8);
value_len += prefix_octets + 6;
pnt += prefix_octets + 6;
+
+ if (ipv6_reach->control_info & CTRL_INFO_SUBTLVS)
+ {
+ if (length <= value_len)
+ {
+ zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLV missing",
+ areatag);
+ retval = ISIS_WARNING;
+ break;
+ }
+ u_char subtlv_len = *pnt;
+ value_len += subtlv_len + 1;
+ pnt += subtlv_len + 1;
+ if (length < value_len)
+ {
+ zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLVs have oversize",
+ areatag);
+ retval = ISIS_WARNING;
+ break;
+ }
+ }
/* FIXME: sub-tlvs */
if (!tlvs->ipv6_reachs)
tlvs->ipv6_reachs = list_new ();
@@ -758,6 +799,9 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
pnt += length;
break;
}
+ /* Abort Parsing if error occured */
+ if (retval != ISIS_OK)
+ return retval;
}
return retval;
diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
index 5a39d564dc..27ded7a0e8 100644
--- a/isisd/isis_tlv.h
+++ b/isisd/isis_tlv.h
@@ -223,7 +223,7 @@ struct te_ipv4_reachability
u_char prefix_start; /* since this is variable length by nature it only */
}; /* points to an approximate location */
-
+#define TE_IPV4_HAS_SUBTLV (0x40)
struct idrp_info
{