[ONOS-8052] BGP-LS : NodeMutiTopology sub-TLV causes BGPParseException

BgpNodeMultitopologyId TLV is called by BgpLinkLSIdentifier. In parseLinkDescriptors
method of BgpLinkLSIdentifier, length is read and then, in switch-case statement, the
control goes to BgpAttrNodeMultiTopologyId.java , where read() method again tries to
read the length. This is the root cause of the BGPParseException in certain BGP packets.

This has been fixed by passing the length from BgpLinkLSIdentifier to
BgpAttrNodeMultiTopologyId. And ofcourse, the same change had to be implemented in other
TLVs which included BgpAttrNodeMultiTopologyId.wq

Change-Id: I662d5f7007e8c92a863fb63ca9ebc7ba2038811a
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java
index 0c82a94..28086c3 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java
@@ -165,7 +165,7 @@
                 tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE);
                 break;
             case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
-                tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
+                tlv = BgpAttrNodeMultiTopologyId.read(tempCb, length);
                 count++;
                 log.debug("MultiTopologyId TLV cannot repeat more than once");
                 if (count > 1) {
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java
index f9cf63f..989253d 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java
@@ -148,7 +148,7 @@
                 isIpReachInfo = true;
                 break;
             case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
-                tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
+                tlv = BgpAttrNodeMultiTopologyId.read(tempCb, length);
                 count = count + 1;
                 if (count > 1) {
                     //length + 4 implies data contains type, length and value
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
index 0e61062..4c2bd67 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
@@ -168,7 +168,8 @@
 
             /********* 7 NODE ATTRIBUTES ********/
             case ATTR_NODE_MT_TOPOLOGY_ID: /* 263 Multi-Topology Identifier*/
-                bgpLSAttrib = BgpAttrNodeMultiTopologyId.read(tempCb);
+                int tlvLength = tempCb.readShort();
+                bgpLSAttrib = BgpAttrNodeMultiTopologyId.read(tempCb, tlvLength);
                 break;
 
             case ATTR_NODE_FLAG_BITS: /*Node flag bit TLV*/
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java
index 219d32f..1f32c32 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java
@@ -66,23 +66,24 @@
      * Reads the Multi-topology ID of Node attribute.
      *
      * @param cb ChannelBuffer
+     * @param len Length of the TLV
      * @return Constructor of BgpAttrNodeMultiTopologyId
      * @throws BgpParseException while parsing BgpAttrNodeMultiTopologyId
      */
-    public static BgpAttrNodeMultiTopologyId read(ChannelBuffer cb)
+    public static BgpAttrNodeMultiTopologyId read(ChannelBuffer cb, int len)
             throws BgpParseException {
         ArrayList<Short> multiTopologyId = new ArrayList<Short>();
         short tempMultiTopologyId;
-        short lsAttrLength = cb.readShort();
-        int len = lsAttrLength / 2; // Length is 2*n and n is the number of MT-IDs
+        //short lsAttrLength = cb.readShort();
+        int numOfMtid = len / 2; // Length is 2*n and n is the number of MT-IDs
 
-        if (cb.readableBytes() < lsAttrLength) {
+        if (cb.readableBytes() < len) {
             Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                    BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
-                                   lsAttrLength);
+                                   len);
         }
 
-        for (int i = 0; i < len; i++) {
+        for (int i = 0; i < numOfMtid; i++) {
             tempMultiTopologyId = cb.readShort();
             multiTopologyId.add(new Short(tempMultiTopologyId));
         }
@@ -161,4 +162,4 @@
         }
         return 0;
     }
-}
\ No newline at end of file
+}