]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: parse TE-IP reachability and IPv6 reachability subtlvs 140/head
authorChristian Franke <chris@opensourcerouting.org>
Tue, 31 Jan 2017 15:10:25 +0000 (16:10 +0100)
committerChristian Franke <chris@opensourcerouting.org>
Tue, 31 Jan 2017 15:13:23 +0000 (16:13 +0100)
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
isisd/isis_tlv.c
isisd/isis_tlv.h

index 1d29d78287b23ffca0f991c6c2a674ae22d97be7..b19a181a3f0024a313a2c497ccd882056bcb2c79 100644 (file)
@@ -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;
index 5a39d564dc886dddd1ac3c793db69a59a7c6e941..27ded7a0e89016e05e1e816b4ced30133cf95379 100644 (file)
@@ -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
 {