Fix for Bug 8005. Parsing Sub Tlv for multiple neighbors
Change-Id: I32c86793db14698280199dd24f9a0e3731fb9771
(cherry picked from commit 8bfea5ec60caa14aa61b4efba1758f0394be8a4e)
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIs.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIs.java
index 41265d1..b248dec 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIs.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIs.java
@@ -102,7 +102,11 @@
this.setMetric(channelBuffer.readUnsignedMedium());
int nTlvPresent = channelBuffer.readByte();
if (nTlvPresent > 0) {
- while (channelBuffer.readableBytes() > IsisUtil.TWO_BYTES) {
+ /* ntlvPresent=0 infers that all Sub TLVs,
+ for a particular neighbor,
+ have been parsed and the loop has to be terminated
+ */
+ while (channelBuffer.readableBytes() > IsisUtil.TWO_BYTES && nTlvPresent > 0) {
TlvHeader tlvHeader = new TlvHeader();
tlvHeader.setTlvType(channelBuffer.readByte());
tlvHeader.setTlvLength(channelBuffer.readByte());
@@ -115,10 +119,18 @@
if (subTlv != null) {
this.addSubTlv(subTlv);
}
+ /*As one Sub TLV is parsed, its length is
+ subtracted from total length to be read
+ */
+ nTlvPresent = nTlvPresent - (tlvLength + IsisUtil.TWO_BYTES);
}
} else {
if (channelBuffer.readableBytes() >= tlvLength) {
channelBuffer.readBytes(tlvLength);
+ /*As one Sub TLV is parsed, its length is
+ subtracted from total length to be read
+ */
+ nTlvPresent = nTlvPresent - (tlvLength + IsisUtil.TWO_BYTES);
}
}
}
@@ -151,4 +163,4 @@
.add("teSubTlv", teSubTlv)
.toString();
}
-}
\ No newline at end of file
+}
diff --git a/protocols/isis/isisio/src/test/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIsTest.java b/protocols/isis/isisio/src/test/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIsTest.java
new file mode 100644
index 0000000..72c93c0
--- /dev/null
+++ b/protocols/isis/isisio/src/test/java/org/onosproject/isis/io/isispacket/tlv/NeighborForExtendedIsTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.isis.io.isispacket.tlv;
+
+import org.easymock.EasyMock;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit test class for NeighborForExtendedIs.
+ *
+ * Here we have passed a byte array containing data for 2 neighbors along with
+ * their Sub TLVs. The test case checks whether the code is able to parse the Sub TLVs
+ * for each neighbor or not. Along with this it also checks for neighbor id and metric
+ * assigned to each neighbor.
+ */
+public class NeighborForExtendedIsTest {
+ private final byte[] tlv = {
+ (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x0a, (byte) 0x3f, (byte) 0x06, (byte) 0x04, (byte) 0x14, (byte) 0x14, (byte) 0x14,
+ (byte) 0xbe, (byte) 0x08, (byte) 0x04, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0xd1, (byte) 0x09,
+ (byte) 0x04, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x0a, (byte) 0x04, (byte) 0x49,
+ (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x0b, (byte) 0x20, (byte) 0x49, (byte) 0x98, (byte) 0x96,
+ (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96,
+ (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96,
+ (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96,
+ (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x12, (byte) 0x03, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x01,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0a, (byte) 0x3f, (byte) 0x06, (byte) 0x04, (byte) 0x1e,
+ (byte) 0x1e, (byte) 0x1e, (byte) 0xce, (byte) 0x08, (byte) 0x04, (byte) 0x1e, (byte) 0x1e, (byte) 0x1e,
+ (byte) 0xa9, (byte) 0x09, (byte) 0x04, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x0a,
+ (byte) 0x04, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x0b, (byte) 0x20, (byte) 0x49,
+ (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49,
+ (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49,
+ (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49,
+ (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x12,
+ (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+
+ //tlv2 bytes are for testing the else part of readFrom() method
+ private final byte[] tlv2 = {
+ (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x0a, (byte) 0x06, (byte) 0x2D, (byte) 0x04, (byte) 0x14, (byte) 0x14, (byte) 0x14,
+ (byte) 0xbe, (byte) 0x2D, (byte) 0xd1, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0xd1, (byte) 0x09
+ };
+ private final String neighborId1 = "1000.1000.1002.00";
+ private final String neighborId2 = "1000.1000.1001.00";
+ private final int metric = 10;
+ private final int subTlvLength = 6;
+ private NeighborForExtendedIs neighborForExtendedIs;
+ private ChannelBuffer channelBuffer;
+
+ @Before
+ public void setUp() throws Exception {
+ neighborForExtendedIs = new NeighborForExtendedIs();
+ channelBuffer = EasyMock.createMock(ChannelBuffer.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ neighborForExtendedIs = null;
+ channelBuffer = null;
+ }
+
+ /**
+ * Tests readFrom() method.
+ */
+ @Test
+ public void testReadFrom() throws Exception {
+ channelBuffer = ChannelBuffers.copiedBuffer(tlv);
+ neighborForExtendedIs.readFrom(channelBuffer);
+ assertThat(neighborForExtendedIs.teSubTlv().size(), is(subTlvLength));
+ assertThat(neighborForExtendedIs.neighborId(), is(neighborId1));
+ assertThat(neighborForExtendedIs.metric(), is(metric));
+
+ neighborForExtendedIs = new NeighborForExtendedIs();
+ neighborForExtendedIs.readFrom(channelBuffer);
+ assertThat(neighborForExtendedIs.teSubTlv().size(), is(subTlvLength));
+ assertThat(neighborForExtendedIs.neighborId(), is(neighborId2));
+ assertThat(neighborForExtendedIs.metric(), is(metric));
+ }
+
+ /**
+ * Tests else condition of readFrom() method.
+ */
+ @Test
+ public void testElsePartOfReadFrom() throws Exception {
+ channelBuffer = ChannelBuffers.copiedBuffer(tlv2);
+ neighborForExtendedIs = new NeighborForExtendedIs();
+ neighborForExtendedIs.readFrom(channelBuffer);
+ assertThat(neighborForExtendedIs.neighborId(), is(neighborId1));
+ assertThat(neighborForExtendedIs.metric(), is(metric));
+ }
+}