diff --git a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateLinkStateAttrTest.java b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateLinkStateAttrTest.java
new file mode 100644
index 0000000..eda343f
--- /dev/null
+++ b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateLinkStateAttrTest.java
@@ -0,0 +1,1975 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.bgpio.protocol;
+
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType;
+import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
+import org.onosproject.bgpio.types.AsPath;
+import org.onosproject.bgpio.types.BgpHeader;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.LinkStateAttributes;
+import org.onosproject.bgpio.types.Med;
+import org.onosproject.bgpio.types.MpReachNlri;
+import org.onosproject.bgpio.types.Origin;
+import org.onosproject.bgpio.types.Origin.ORIGINTYPE;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeName;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpAttrOpaqueNode;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIsIsAdminstGrp;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMplsProtocolMask;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrOpaqLnkAttrib;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType.ProtectionType;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrSrlg;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrOpaqueData;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrRouteTag;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * UT for Update Message (Link State Attribute and all its TLVs).
+ */
+public class BgpUpdateLinkStateAttrTest {
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrIGPMetric.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest1() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x95,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7A, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrNodeRouterId
+                0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x0a}; //BgpLinkAttrIGPMetric
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 149));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        //compare Origin
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        //compare Aspath
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        //compare MED
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        //compare Mpreach
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        //compare LinkStateAttributes
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x0f, 0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c,
+                0x62, 0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x0a };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeRouterId.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest2() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x06, 0x00, 0x04, 0x16, 0x16, 0x16, 0x16}; //BgpAttrNodeRouterId
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath asPath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x04, 0x06, 0x00, 0x04, 0x16, 0x16, 0x16, 0x16 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrMetric.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest3() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, (byte) 0x83, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; //BgpPrefixAttrMetric
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x04, (byte) 0x83, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeName.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest4() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x98,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7d, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x12,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x02, 0x00, 0x06, 0x37, 0x37, 0x35, 0x30, 0x2d, 0x31 }; //BgpAttrNodeName
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 152));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x12, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x04, 0x02, 0x00, 0x06, 0x37, 0x37, 0x35, 0x30, 0x2d, 0x31 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
+        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
+        assertThat(list.next(), is(list2.next()));
+        assertThat(((BgpAttrNodeName) list2.next()).attrNodeName(), is(((BgpAttrNodeName) list.next()).attrNodeName()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeIsIsAreaId.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest5() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x95,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7A, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrNodeRouterId
+                0x04, 0x03, 0x00, 0x03, 0x40, 0x01, 0x00}; //BgpAttrNodeIsIsAreaId
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 149));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x0f, 0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c,
+                0x62, 0x04, 0x03, 0x00, 0x03, 0x40, 0x01, 0x00 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
+        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
+        assertThat(list.next(), is(list2.next()));
+        assertThat(((BgpAttrNodeIsIsAreaId) list2.next()).attrNodeIsIsAreaId(),
+                is(((BgpAttrNodeIsIsAreaId) list.next()).attrNodeIsIsAreaId()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrRouterIdV6.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest6() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xA2,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, (byte) 0x87, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x1C,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x05, 0x00, 0x10, 0x01, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01}; //BgpAttrRouterIdV6
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 162));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x1C, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x04, 0x05, 0x00, 0x10, 0x01, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeMultiTopologyId.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest7() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x01, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02}; //BgpAttrNodeMultiTopologyId
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x01, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
+        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
+        assertThat(list.next(), is(list2.next()));
+        assertThat(((BgpAttrNodeMultiTopologyId) list2.next()).attrMultiTopologyId(),
+                is(((BgpAttrNodeMultiTopologyId) list.next()).attrMultiTopologyId()));
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrRouteTag.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest8() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, (byte) 0x81, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01}; //BgpPrefixAttrRouteTag
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
+                0x15, 0x04, (byte) 0x81, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01 };
+        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
+        cb.writeBytes(linkAttrbs);
+        LinkStateAttributes obj = LinkStateAttributes.read(cb);
+
+        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
+        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
+        assertThat(list.next(), is(list2.next()));
+        assertThat(((BgpPrefixAttrRouteTag) list2.next()).getPfxRouteTag(),
+                is(((BgpPrefixAttrRouteTag) list.next()).getPfxRouteTag()));
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrIsIsAdminstGrp.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest9() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; //BgpLinkAttrIsIsAdminstGrp
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        assertThat(((BgpLinkAttrIsIsAdminstGrp) list.next()).linkAttrIsIsAdminGrp(), is((long) 0));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeFlagBitTlv.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest10() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x93,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x78, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0D,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x00, 0x00, 0x01, 0x20}; //BgpAttrNodeFlagBitTlv
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 147));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        BgpAttrNodeFlagBitTlv obj = new BgpAttrNodeFlagBitTlv(false, false, true, false);
+        assertThat(((BgpAttrNodeFlagBitTlv) list.next()).equals(obj), is(true));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrTeDefaultMetric.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest11() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7B, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, 0x44, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a}; //BgpLinkAttrTeDefaultMetric
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        assertThat(((BgpLinkAttrTeDefaultMetric) list.next()).attrLinkDefTeMetric(), is(10));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrOpaqueNode.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest12() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7B, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a}; //BgpAttrOpaqueNode
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        byte[] opaqueNode = new byte[] {0x00, 0x00, 0x00, 0x0a };
+        assertThat(((BgpAttrOpaqueNode) list.next()).attrOpaqueNode(), is(opaqueNode));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrProtectionType.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest13() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x94,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x79, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0E,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x45, 0x00, 0x02, 0x10, 0x00}; //BgpLinkAttrProtectionType
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 148));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        assertThat(((BgpLinkAttrProtectionType) list.next()).protectionType(),
+                is(ProtectionType.DEDICATED_ONE_PLUS_ONE));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrMplsProtocolMask.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest14() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x93,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x78, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0D,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x46, 0x00, 0x01, (byte) 0xC0}; //BgpLinkAttrMplsProtocolMask
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 147));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        BgpLinkAttrMplsProtocolMask obj = new BgpLinkAttrMplsProtocolMask(true, true);
+        assertThat(((BgpLinkAttrMplsProtocolMask) list.next()).equals(obj), is(true));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrSRLG.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest15() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x9A,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7F, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x14,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x48, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b}; //BgpLinkAttrSRLG
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 154));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        List<Integer> attrSrlg = new ArrayList<Integer>();
+        attrSrlg.add(10);
+        attrSrlg.add(11);
+        assertThat(((BgpLinkAttrSrlg) list.next()).attrSrlg(), is(attrSrlg));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrOpaqLnkAttrib.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest16() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x9A,
+                0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7F, 0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01,  0x00,
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, (byte) 0x80, 0x1d, 0x14,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x49, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b}; //BgpLinkAttrOpaqLnkAttrib
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 154));
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        byte[] attrOpaqLnkAttrib = new byte[] {0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b };
+        assertThat(((BgpLinkAttrOpaqLnkAttrib) list.next()).attrOpaqueLnk(), is(attrOpaqLnkAttrib));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrOpaqueData.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest17() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, 0x00, 0x7B, //path attribute len
+                0x04, 0x01, 0x01, 0x00, 0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, 0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, (byte) 0x85, 0x00, 0x04, 0x0a, 0x0a, 0x0a, 0x0a}; //BgpPrefixAttrOpaqueData
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 150));
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        byte[] opaquePrefixAttr = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+        assertThat(((BgpPrefixAttrOpaqueData) list.next()).getOpaquePrefixAttribute(), is(opaquePrefixAttr));
+    }
+}
diff --git a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateMsgTest.java b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateMsgTest.java
old mode 100755
new mode 100644
index 8e1cd20..69ba01a
--- a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateMsgTest.java
+++ b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpUpdateMsgTest.java
@@ -1,1496 +1,1996 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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.bgpio.protocol;
-
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.core.Is.is;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.junit.Test;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onosproject.bgpio.exceptions.BgpParseException;
-import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
-import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType;
-import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
-import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
-import org.onosproject.bgpio.types.As4Path;
-import org.onosproject.bgpio.types.AsPath;
-import org.onosproject.bgpio.types.AutonomousSystemTlv;
-import org.onosproject.bgpio.types.BgpHeader;
-import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
-import org.onosproject.bgpio.types.BgpValueType;
-import org.onosproject.bgpio.types.IPReachabilityInformationTlv;
-import org.onosproject.bgpio.types.IsIsNonPseudonode;
-import org.onosproject.bgpio.types.IsIsPseudonode;
-import org.onosproject.bgpio.types.Med;
-import org.onosproject.bgpio.types.MpReachNlri;
-import org.onosproject.bgpio.types.MpUnReachNlri;
-import org.onosproject.bgpio.types.Origin;
-import org.onosproject.bgpio.types.NextHop;
-import org.onosproject.bgpio.types.LocalPref;
-import org.onosproject.bgpio.types.Origin.ORIGINTYPE;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * Test cases for BGP update Message.
- */
-public class BgpUpdateMsgTest {
-    protected static final Logger log = LoggerFactory.getLogger(BgpUpdateMsgTest.class);
-    public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
-    public static final byte UPDATE_MSG_TYPE = 0x2;
-
-    /**
-     * This test case checks update message with no withdrawn routes
-     * and path attributes.
-     */
-    @Test
-    public void bgpUpdateMessageTest01() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x02, 0x00, 0x00, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 23));
-    }
-
-    /**
-     * In this test case, Marker is set as 0 in input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest02() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x02, 0x00, 0x00, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid message length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest03() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid message type is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest04() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x06, 0x00, 0x00, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with withdrawn routes.
-     */
-    @Test
-    public void bgpUpdateMessageTest05() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 27));
-
-        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
-        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 24));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-    }
-
-    /**
-     * In this test case, Invalid withdrawn route length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest06() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x19, 0x0a, 0x01, 0x01, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with path attributes.
-     */
-    @Test
-    public void bgpUpdateMessageTest07() throws BgpParseException {
-        byte[] updateMsg = new byte [] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x01, 0x01,
-                0x00, 0x40, 0x02, 0x00, 0x40, 0x03, 0x04, 0x03, 0x03, 0x03, 0x03, (byte) 0x80, 0x04, 0x04, 0x00, 0x00,
-                0x00, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x64, 0x18, 0x0a, 0x1e, 0x03, 0x18, 0x0a, 0x1e,
-                0x02, 0x18, 0x0a, 0x1e, 0x01};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 63));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        AsPath asPath;
-        NextHop nexthop;
-        Med med;
-        LocalPref localPref;
-
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next(); // AS PATH value is empty in hex dump
-        asPath = (AsPath) testPathAttribute;
-        List<Short> asPathValues = asPath.asPathSeq();
-        assertThat(asPathValues.isEmpty(), is(true));
-
-        testPathAttribute = listIterator.next();
-        nexthop = (NextHop) testPathAttribute;
-        byte[] nextHopAddr = new byte[] {0x03, 0x03, 0x03, 0x03};
-        assertThat(nexthop.nextHop().toOctets(), is(nextHopAddr));
-
-        testPathAttribute = listIterator.next();
-        med = (Med) testPathAttribute;
-        assertThat(med.med(), is(0));
-
-        testPathAttribute = listIterator.next();
-        localPref = (LocalPref) testPathAttribute;
-        assertThat(localPref.localPref(), is(100));
-
-        ListIterator<IpPrefix> listIterator1 = other.nlri().listIterator();
-        byte[] prefix = new byte[] {0x0a, 0x1e, 0x03, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 24));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-    }
-
-    /**
-     * In this test case, Invalid ORIGIN flags is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest08() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid ORIGIN value is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest09() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x04, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, update message without path attribute is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest10() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x1a, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, update message with incorrect path attribute length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest11() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x01};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid MED flags is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest12() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0xff, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid AS Path flags is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest13() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                (byte) 0xff, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid MP reach flags is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest14() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0xff, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid SAFI is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest15() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x49, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid AFI is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest16() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x06, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid res is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest17() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                (byte) 0xff, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x01, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with node NLRI.
-     */
-    @Test
-    public void bgpUpdateMessageTest18() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 96));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        AsPath asPath;
-        Med med;
-        MpReachNlri mpReach;
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next();
-        asPath = (AsPath) testPathAttribute;
-        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
-        assertThat(listIterator2.next(), is((short) 65001));
-
-        testPathAttribute = listIterator.next();
-        med = (Med) testPathAttribute;
-        assertThat(med.med(), is(0));
-
-        testPathAttribute = listIterator.next();
-        mpReach = (MpReachNlri) testPathAttribute;
-        assertThat(mpReach.mpReachNlriLen(), is((int) 52));
-        assertThat(mpReach.getType(), is((short) 14));
-
-        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
-        testMpReachNlri = mpReach.mpReachNlri();
-
-        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
-        BgpLSNlri testnlri =  list1.next();
-        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.NODE;
-        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
-        BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
-        assertThat(testnlri.getIdentifier(), is((long) 0));
-        assertThat(testnlri.getNlriType(), is(nlriType));
-        assertThat(testnlri.getProtocolId(), is(protocolId));
-
-        BgpNodeLSNlriVer4 testNodenlri = (BgpNodeLSNlriVer4) testnlri;
-
-        BgpNodeLSIdentifier testLocalNodeDescriptors = testNodenlri.getLocalNodeDescriptors();
-
-        List<BgpValueType> testSubTlvs = new LinkedList<>();
-        NodeDescriptors localNodeDescriptors = testLocalNodeDescriptors.getNodedescriptors();
-        testSubTlvs = localNodeDescriptors.getSubTlvs();
-        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
-
-        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
-        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
-        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
-
-        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
-        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
-        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
-
-        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
-        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
-        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
-        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
-
-    }
-
-    /**
-     * This test case checks update message with prefix NLRI.
-     */
-    @Test
-    public void bgpUpdateMessageTest19() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
-                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, (byte) 0xbb, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
-                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
-                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
-                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
-                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
-                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
-                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
-                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
-                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
-                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
-                0x16, 0x16, 0x16, 0x16}; // prefix nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 214));
-
-        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
-        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 24));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        AsPath asPath;
-        Med med;
-        MpReachNlri mpReach;
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next();
-        asPath = (AsPath) testPathAttribute;
-        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
-        assertThat(listIterator2.next(), is((short) 65001));
-
-        testPathAttribute = listIterator.next();
-        med = (Med) testPathAttribute;
-        assertThat(med.med(), is(0));
-
-        testPathAttribute = listIterator.next();
-        mpReach = (MpReachNlri) testPathAttribute;
-        assertThat(mpReach.mpReachNlriLen(), is((int) 165));
-        assertThat(mpReach.getType(), is((short) 14));
-
-        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
-        testMpReachNlri = mpReach.mpReachNlri();
-
-        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
-        BgpLSNlri testnlri =  list1.next();
-        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.PREFIX_IPV4;
-        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
-                BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
-        assertThat(testnlri.getIdentifier(), is((long) 0));
-        assertThat(testnlri.getNlriType(), is(nlriType));
-        assertThat(testnlri.getProtocolId(), is(protocolId));
-
-        BgpPrefixLSNlri testprefixnlri = (BgpPrefixLSNlri) testnlri;
-
-        NodeDescriptors testLocalNodeDescriptors = testprefixnlri.getLocalNodeDescriptors();
-
-        List<BgpValueType> testSubTlvs = new LinkedList<>();
-        testSubTlvs = testLocalNodeDescriptors.getSubTlvs();
-        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
-
-        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
-        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
-        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
-
-        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
-        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
-        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
-
-        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
-        byte[] expISONodeID = new byte[] {0x19, 0x21, 0x68, 0x07, 0x70, 0x01};
-        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
-        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
-
-        List<BgpValueType> testPrefixDescriptors =  new LinkedList<>();
-        testPrefixDescriptors = testprefixnlri.getPrefixdescriptor();
-        ListIterator<BgpValueType> subtlvlist2 = testPrefixDescriptors.listIterator();
-        IPReachabilityInformationTlv testIPReachabilityInformationTlv = (IPReachabilityInformationTlv)
-                subtlvlist2.next();
-        byte[] address = new byte[] {(byte) 0xc0, (byte) 0xa8, 0x4d, 0x01};
-        IpPrefix prefix1 = IpPrefix.valueOf(IpAddress.Version.INET, address, 32);
-        assertThat(testIPReachabilityInformationTlv.getPrefixValue(), is(prefix1));
-        assertThat(testIPReachabilityInformationTlv.getPrefixLen(), is((byte) 32));
-    }
-
-    /**
-     * This test case checks update message with link NLRI.
-     */
-    @Test
-    public void bgpUpdateMessageTest20() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x83, 0x02, 0x00, 0x04,
-                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, 0x68, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
-                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
-                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
-                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
-                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
-                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
-                0x00, (byte) 0x95, 0x02, 0x50, 0x21//link nlri
-        };
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message = null;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 131));
-
-        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
-        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 24));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        AsPath asPath;
-        Med med;
-        MpReachNlri mpReach;
-
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next();
-        asPath = (AsPath) testPathAttribute;
-        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
-        assertThat(listIterator2.next(), is((short) 65001));
-
-        testPathAttribute = listIterator.next();
-        med = (Med) testPathAttribute;
-        assertThat(med.med(), is(0));
-
-        testPathAttribute = listIterator.next();
-        mpReach = (MpReachNlri) testPathAttribute;
-        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
-        assertThat(mpReach.getType(), is((short) 14));
-
-        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
-        testMpReachNlri = mpReach.mpReachNlri();
-
-        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
-        BgpLSNlri testnlri =  list1.next();
-        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
-        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
-            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
-        assertThat(testnlri.getIdentifier(), is((long) 0));
-        assertThat(testnlri.getNlriType(), is(nlriType));
-        assertThat(testnlri.getProtocolId(), is(protocolId));
-
-        BgpLinkLsNlriVer4 testlinknlri = (BgpLinkLsNlriVer4) testnlri;
-
-        NodeDescriptors testLocalNodeDescriptors = testlinknlri.localNodeDescriptors();
-
-        List<BgpValueType> testSubTlvs = new LinkedList<>();
-        testSubTlvs = testLocalNodeDescriptors.getSubTlvs();
-        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
-
-        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
-
-        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
-        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
-
-        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
-        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
-        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
-
-        IsIsPseudonode testIsIsPseudonode = (IsIsPseudonode) subtlvlist1.next();
-        assertThat(testIsIsPseudonode.getPSNIdentifier(), is((byte) 3));
-        assertThat(testIsIsPseudonode.getType(), is((short) 515));
-
-        NodeDescriptors testRemoteNodeDescriptors = testlinknlri.remoteNodeDescriptors();
-        testSubTlvs = testRemoteNodeDescriptors.getSubTlvs();
-        ListIterator<BgpValueType> subtlvlist2 = testSubTlvs.listIterator();
-
-        testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist2.next();
-
-        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
-        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
-
-        testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist2.next();
-        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
-        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
-
-        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist2.next();
-        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21};
-        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
-        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
-    }
-
-    /**
-     * In this test case, Invalid withdrawn route length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest21() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x07, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid withdrawn route length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest22() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x25, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x0e, //path attribute len
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Mandatory attributes are not given in input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest23() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x12, //path attribute len
-                0x0e, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid origin length is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest24() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x12, //path attribute len
-                0x04, 0x01, 0x02, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid origin value is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest25() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x12, //path attribute len
-                0x04, 0x01, 0x01, 0x04, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid descriptor type in node nlri is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest26() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, Invalid node nlri length field in is given as input and expecting
-     * an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest27() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
-                0x00, 0x49, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, withdrawn routes with prefix length 0 is given as input and expecting
-     * an exception.
-     */
-    @Test
-    public void bgpUpdateMessageTest28() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, //marker
-                0x00, 0x18, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * In this test case, update message without total Path Attribute Length field is given as
-     * input and expecting an exception.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest29() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, //marker
-                0x00, 0x16, 0x02, 0x00, 0x01, 0x00};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with as4 path attribute.
-     */
-    @Test
-    public void bgpUpdateMessageTest30() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                0x00, 0x3a, 0x02, 0x00, 0x00, 0x00, 0x21, 0x40, 0x01, 0x01, 0x00, (byte) 0xc0,
-                0x11, 0x0a, 0x02, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x28, 0x00, 0x01, 0x40,
-                0x02, 0x06, 0x02, 0x02, 0x5b, (byte) 0xa0, 0x5b, (byte) 0xa0, 0x40, 0x03, 0x04,
-                (byte) 0xac, 0x10, 0x03, 0x01, 0x08, 0x28};
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message = null;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 58));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        As4Path as4Path;
-        AsPath asPath;
-        NextHop nextHop;
-
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next();
-        as4Path = (As4Path) testPathAttribute;
-        ListIterator<Integer> listIterator2 = as4Path.as4PathSEQ().listIterator();
-        assertThat(listIterator2.next(), is(655361));
-
-        testPathAttribute = listIterator.next();
-        asPath = (AsPath) testPathAttribute;
-        ListIterator<Short> listIterator3 = asPath.asPathSeq().listIterator();
-        assertThat(listIterator3.next(), is((short) 23456));
-
-        testPathAttribute = listIterator.next();
-        nextHop = (NextHop) testPathAttribute;
-        byte[] nextHopAddr = new byte[] {(byte) 0xac, 0x10, 0x03, 0x01};
-        assertThat(nextHop.nextHop().toOctets(), is(nextHopAddr));
-
-        ListIterator<IpPrefix> listIterator1 = other.nlri().listIterator();
-        byte[] prefix = new byte[] {0x28, 0x00, 0x00, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 8));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-    }
-
-    /**
-     * This test case checks update message with MPUnreach.
-     */
-    @Test
-    public void bgpUpdateMessageTest31() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, 0x5e, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, 0x43, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0f, 0x2e, 0x40, 0x04, 0x47, //mpunreach with safi = 71
-                0x00, 0x01, 0x00,
-                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
-                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
-                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-        BgpUpdateMsg other = (BgpUpdateMsg) message;
-
-        assertThat(other.getHeader().getMarker(), is(MARKER));
-        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
-        assertThat(other.getHeader().getLength(), is((short) 94));
-
-        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
-        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
-
-        IpPrefix testPrefixValue = listIterator1.next();
-        assertThat(testPrefixValue.prefixLength(), is((int) 24));
-        assertThat(testPrefixValue.address().toOctets(), is(prefix));
-
-        BgpValueType testPathAttribute;
-        Origin origin;
-        AsPath asPath;
-        Med med;
-        MpUnReachNlri mpUnReach;
-        List<BgpValueType> pathAttributes = new LinkedList<>();
-        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
-        pathAttributes = actualpathAttribute.pathAttributes();
-        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
-        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
-
-        testPathAttribute = listIterator.next();
-        origin = (Origin) testPathAttribute;
-        assertThat(origin.origin(), is(originValue));
-
-        testPathAttribute = listIterator.next();
-        asPath = (AsPath) testPathAttribute;
-        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
-        assertThat(listIterator2.next(), is((short) 65001));
-
-        testPathAttribute = listIterator.next();
-        med = (Med) testPathAttribute;
-        assertThat(med.med(), is(0));
-
-        testPathAttribute = listIterator.next();
-        mpUnReach = (MpUnReachNlri) testPathAttribute;
-        assertThat(mpUnReach.mpUnReachNlriLen(), is((int) 46));
-        assertThat(mpUnReach.getType(), is((short) 15));
-
-        List<BgpLSNlri> testMpUnReachNlri = new LinkedList<>();
-        testMpUnReachNlri = mpUnReach.mpUnReachNlri();
-
-        ListIterator<BgpLSNlri> list1 = testMpUnReachNlri.listIterator();
-        BgpLSNlri testnlri =  list1.next();
-        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.NODE;
-        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
-               BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
-        assertThat(testnlri.getIdentifier(), is((long) 0));
-        assertThat(testnlri.getNlriType(), is(nlriType));
-        assertThat(testnlri.getProtocolId(), is(protocolId));
-
-        BgpNodeLSNlriVer4 testNodenlri = (BgpNodeLSNlriVer4) testnlri;
-
-        BgpNodeLSIdentifier testLocalNodeDescriptors = testNodenlri.getLocalNodeDescriptors();
-
-        List<BgpValueType> testSubTlvs = new LinkedList<>();
-        NodeDescriptors localNodeDescriptors = testLocalNodeDescriptors.getNodedescriptors();
-        testSubTlvs = localNodeDescriptors.getSubTlvs();
-        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
-
-        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
-
-        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
-        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
-
-        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
-        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
-        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
-
-        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
-        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
-        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
-        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
-    }
-
-    /**
-     * This test case checks update message with invalid mpreach packet.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest32() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
-                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, (byte) 0xbb, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
-                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
-                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
-                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
-                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
-                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
-                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
-                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
-                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
-                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
-                0x16, 0x16, 0x16, 0x16}; // prefix nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with invalid prefix nlri length in input.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest33() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
-                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, (byte) 0xbb, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x03, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
-                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
-                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
-                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
-                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
-                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
-                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
-                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
-                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
-                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
-                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
-                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
-                0x16, 0x16, 0x16, 0x16}; // prefix nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-
-    /**
-     * This test case checks update message with invalid link nlri length in input.
-     */
-    @Test(expected = BgpParseException.class)
-    public void bgpUpdateMessageTest34() throws BgpParseException {
-        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x83, 0x02, 0x00, 0x04,
-                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
-                0x00, 0x68, //path attribute len
-                0x04, 0x01, 0x01, 0x00, //origin
-                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
-                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
-                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
-                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
-                0x00, //reserved
-                0x00, 0x02, 0x00, 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
-                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
-                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
-                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
-                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
-                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
-                0x00, (byte) 0x95, 0x02, 0x50, 0x21}; //link nlri
-
-        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
-        buffer.writeBytes(updateMsg);
-
-        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
-        BgpMessage message;
-        BgpHeader bgpHeader = new BgpHeader();
-
-        message = reader.readFrom(buffer, bgpHeader);
-
-        assertThat(message, instanceOf(BgpUpdateMsg.class));
-    }
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.bgpio.protocol;
+
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType;
+import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
+import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
+import org.onosproject.bgpio.types.As4Path;
+import org.onosproject.bgpio.types.AsPath;
+import org.onosproject.bgpio.types.AutonomousSystemTlv;
+import org.onosproject.bgpio.types.BgpHeader;
+import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.IPReachabilityInformationTlv;
+import org.onosproject.bgpio.types.IsIsNonPseudonode;
+import org.onosproject.bgpio.types.IsIsPseudonode;
+import org.onosproject.bgpio.types.LinkStateAttributes;
+import org.onosproject.bgpio.types.Med;
+import org.onosproject.bgpio.types.MpReachNlri;
+import org.onosproject.bgpio.types.MpUnReachNlri;
+import org.onosproject.bgpio.types.Origin;
+import org.onosproject.bgpio.types.NextHop;
+import org.onosproject.bgpio.types.LocalPref;
+import org.onosproject.bgpio.types.Origin.ORIGINTYPE;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrName;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrExtRouteTag;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrIgpFlags;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Test cases for BGP update Message.
+ */
+public class BgpUpdateMsgTest {
+    protected static final Logger log = LoggerFactory.getLogger(BgpUpdateMsgTest.class);
+    public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+    public static final byte UPDATE_MSG_TYPE = 0x2;
+
+    /**
+     * This test case checks update message with no withdrawn routes
+     * and path attributes.
+     */
+    @Test
+    public void bgpUpdateMessageTest01() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x02, 0x00, 0x00, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 23));
+    }
+
+    /**
+     * In this test case, Marker is set as 0 in input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest02() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x02, 0x00, 0x00, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid message length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest03() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid message type is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest04() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x17, 0x06, 0x00, 0x00, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with withdrawn routes.
+     */
+    @Test
+    public void bgpUpdateMessageTest05() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 27));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 24));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+    }
+
+    /**
+     * In this test case, Invalid withdrawn route length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest06() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x19, 0x0a, 0x01, 0x01, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with path attributes.
+     */
+    @Test
+    public void bgpUpdateMessageTest07() throws BgpParseException {
+        byte[] updateMsg = new byte [] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x01, 0x01,
+                0x00, 0x40, 0x02, 0x00, 0x40, 0x03, 0x04, 0x03, 0x03, 0x03, 0x03, (byte) 0x80, 0x04, 0x04, 0x00, 0x00,
+                0x00, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x64, 0x18, 0x0a, 0x1e, 0x03, 0x18, 0x0a, 0x1e,
+                0x02, 0x18, 0x0a, 0x1e, 0x01};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 63));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        AsPath asPath;
+        NextHop nexthop;
+        Med med;
+        LocalPref localPref;
+
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next(); // AS PATH value is empty in hex dump
+        asPath = (AsPath) testPathAttribute;
+        List<Short> asPathValues = asPath.asPathSeq();
+        assertThat(asPathValues.isEmpty(), is(true));
+
+        testPathAttribute = listIterator.next();
+        nexthop = (NextHop) testPathAttribute;
+        byte[] nextHopAddr = new byte[] {0x03, 0x03, 0x03, 0x03};
+        assertThat(nexthop.nextHop().toOctets(), is(nextHopAddr));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        localPref = (LocalPref) testPathAttribute;
+        assertThat(localPref.localPref(), is(100));
+
+        ListIterator<IpPrefix> listIterator1 = other.nlri().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x1e, 0x03, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 24));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+    }
+
+    /**
+     * In this test case, Invalid ORIGIN flags is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest08() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid ORIGIN value is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest09() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x04, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, update message without path attribute is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest10() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x1a, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, update message with incorrect path attribute length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest11() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x01};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid MED flags is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest12() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0xff, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid AS Path flags is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest13() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                (byte) 0xff, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid MP reach flags is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest14() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0xff, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid SAFI is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest15() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x49, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid AFI is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest16() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x06, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid res is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest17() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                (byte) 0xff, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x01, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with node NLRI.
+     */
+    @Test
+    public void bgpUpdateMessageTest18() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 96));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        AsPath asPath;
+        Med med;
+        MpReachNlri mpReach;
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 52));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.NODE;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+        BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        BgpNodeLSNlriVer4 testNodenlri = (BgpNodeLSNlriVer4) testnlri;
+
+        BgpNodeLSIdentifier testLocalNodeDescriptors = testNodenlri.getLocalNodeDescriptors();
+
+        List<BgpValueType> testSubTlvs = new LinkedList<>();
+        NodeDescriptors localNodeDescriptors = testLocalNodeDescriptors.getNodedescriptors();
+        testSubTlvs = localNodeDescriptors.getSubTlvs();
+        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
+
+        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
+        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
+        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
+
+        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
+        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
+        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
+
+        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
+        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
+        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
+        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
+
+    }
+
+    /**
+     * This test case checks update message with prefix NLRI.
+     */
+    @Test
+    public void bgpUpdateMessageTest19() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, (byte) 0xbb, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
+                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
+                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
+                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
+                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
+                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
+                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
+                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
+                0x16, 0x16, 0x16, 0x16}; // prefix nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 214));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 24));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        AsPath asPath;
+        Med med;
+        MpReachNlri mpReach;
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 165));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.PREFIX_IPV4;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+                BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        BgpPrefixLSNlri testprefixnlri = (BgpPrefixLSNlri) testnlri;
+
+        NodeDescriptors testLocalNodeDescriptors = testprefixnlri.getLocalNodeDescriptors();
+
+        List<BgpValueType> testSubTlvs = new LinkedList<>();
+        testSubTlvs = testLocalNodeDescriptors.getSubTlvs();
+        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
+
+        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
+        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
+        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
+
+        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
+        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
+        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
+
+        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
+        byte[] expISONodeID = new byte[] {0x19, 0x21, 0x68, 0x07, 0x70, 0x01};
+        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
+        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
+
+        List<BgpValueType> testPrefixDescriptors =  new LinkedList<>();
+        testPrefixDescriptors = testprefixnlri.getPrefixdescriptor();
+        ListIterator<BgpValueType> subtlvlist2 = testPrefixDescriptors.listIterator();
+        IPReachabilityInformationTlv testIPReachabilityInformationTlv = (IPReachabilityInformationTlv)
+                subtlvlist2.next();
+        byte[] address = new byte[] {(byte) 0xc0, (byte) 0xa8, 0x4d, 0x01};
+        IpPrefix prefix1 = IpPrefix.valueOf(IpAddress.Version.INET, address, 32);
+        assertThat(testIPReachabilityInformationTlv.getPrefixValue(), is(prefix1));
+        assertThat(testIPReachabilityInformationTlv.getPrefixLen(), is((byte) 32));
+    }
+
+    /**
+     * This test case checks update message with link NLRI.
+     */
+    @Test
+    public void bgpUpdateMessageTest20() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x83, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x68, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21//link nlri
+        };
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 131));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 24));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        AsPath asPath;
+        Med med;
+        MpReachNlri mpReach;
+
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        BgpLinkLsNlriVer4 testlinknlri = (BgpLinkLsNlriVer4) testnlri;
+
+        NodeDescriptors testLocalNodeDescriptors = testlinknlri.localNodeDescriptors();
+
+        List<BgpValueType> testSubTlvs = new LinkedList<>();
+        testSubTlvs = testLocalNodeDescriptors.getSubTlvs();
+        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
+
+        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
+
+        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
+        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
+
+        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
+        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
+        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
+
+        IsIsPseudonode testIsIsPseudonode = (IsIsPseudonode) subtlvlist1.next();
+        assertThat(testIsIsPseudonode.getPSNIdentifier(), is((byte) 3));
+        assertThat(testIsIsPseudonode.getType(), is((short) 515));
+
+        NodeDescriptors testRemoteNodeDescriptors = testlinknlri.remoteNodeDescriptors();
+        testSubTlvs = testRemoteNodeDescriptors.getSubTlvs();
+        ListIterator<BgpValueType> subtlvlist2 = testSubTlvs.listIterator();
+
+        testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist2.next();
+
+        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
+        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
+
+        testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist2.next();
+        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
+        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
+
+        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist2.next();
+        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21};
+        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
+        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
+    }
+
+    /**
+     * In this test case, Invalid withdrawn route length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest21() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x1b, 0x02, 0x00, 0x07, 0x18, 0x0a, 0x01, 0x01, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid withdrawn route length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest22() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x25, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x0e, //path attribute len
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Mandatory attributes are not given in input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest23() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x12, //path attribute len
+                0x0e, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid origin length is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest24() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x12, //path attribute len
+                0x04, 0x01, 0x02, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid origin value is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest25() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x29, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x12, //path attribute len
+                0x04, 0x01, 0x01, 0x04, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; //med
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid descriptor type in node nlri is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest26() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, Invalid node nlri length field in is given as input and expecting
+     * an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest27() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x60, 0x02, 0x00, 0x00, //withdrawn len
+                0x00, 0x49, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x34, 0x40, 0x04, 0x47, //mpreach with safi = 71
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, withdrawn routes with prefix length 0 is given as input and expecting
+     * an exception.
+     */
+    @Test
+    public void bgpUpdateMessageTest28() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, //marker
+                0x00, 0x18, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * In this test case, update message without total Path Attribute Length field is given as
+     * input and expecting an exception.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest29() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, //marker
+                0x00, 0x16, 0x02, 0x00, 0x01, 0x00};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with as4 path attribute.
+     */
+    @Test
+    public void bgpUpdateMessageTest30() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                0x00, 0x3a, 0x02, 0x00, 0x00, 0x00, 0x21, 0x40, 0x01, 0x01, 0x00, (byte) 0xc0,
+                0x11, 0x0a, 0x02, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x28, 0x00, 0x01, 0x40,
+                0x02, 0x06, 0x02, 0x02, 0x5b, (byte) 0xa0, 0x5b, (byte) 0xa0, 0x40, 0x03, 0x04,
+                (byte) 0xac, 0x10, 0x03, 0x01, 0x08, 0x28};
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 58));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        As4Path as4Path;
+        AsPath asPath;
+        NextHop nextHop;
+
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        as4Path = (As4Path) testPathAttribute;
+        ListIterator<Integer> listIterator2 = as4Path.as4PathSEQ().listIterator();
+        assertThat(listIterator2.next(), is(655361));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator3 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator3.next(), is((short) 23456));
+
+        testPathAttribute = listIterator.next();
+        nextHop = (NextHop) testPathAttribute;
+        byte[] nextHopAddr = new byte[] {(byte) 0xac, 0x10, 0x03, 0x01};
+        assertThat(nextHop.nextHop().toOctets(), is(nextHopAddr));
+
+        ListIterator<IpPrefix> listIterator1 = other.nlri().listIterator();
+        byte[] prefix = new byte[] {0x28, 0x00, 0x00, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 8));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+    }
+
+    /**
+     * This test case checks update message with MPUnreach.
+     */
+    @Test
+    public void bgpUpdateMessageTest31() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, 0x5e, 0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x43, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0f, 0x2e, 0x40, 0x04, 0x47, //mpunreach with safi = 71
+                0x00, 0x01, 0x00,
+                0x27, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00,
+                0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+                0x00, 0x06, 0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; //node nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        assertThat(other.getHeader().getMarker(), is(MARKER));
+        assertThat(other.getHeader().getType(), is(UPDATE_MSG_TYPE));
+        assertThat(other.getHeader().getLength(), is((short) 94));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        IpPrefix testPrefixValue = listIterator1.next();
+        assertThat(testPrefixValue.prefixLength(), is((int) 24));
+        assertThat(testPrefixValue.address().toOctets(), is(prefix));
+
+        BgpValueType testPathAttribute;
+        Origin origin;
+        AsPath asPath;
+        Med med;
+        MpUnReachNlri mpUnReach;
+        List<BgpValueType> pathAttributes = new LinkedList<>();
+        BgpPathAttributes actualpathAttribute = other.bgpPathAttributes();
+        pathAttributes = actualpathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributes.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        asPath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpUnReach = (MpUnReachNlri) testPathAttribute;
+        assertThat(mpUnReach.mpUnReachNlriLen(), is((int) 46));
+        assertThat(mpUnReach.getType(), is((short) 15));
+
+        List<BgpLSNlri> testMpUnReachNlri = new LinkedList<>();
+        testMpUnReachNlri = mpUnReach.mpUnReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpUnReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.NODE;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+               BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        BgpNodeLSNlriVer4 testNodenlri = (BgpNodeLSNlriVer4) testnlri;
+
+        BgpNodeLSIdentifier testLocalNodeDescriptors = testNodenlri.getLocalNodeDescriptors();
+
+        List<BgpValueType> testSubTlvs = new LinkedList<>();
+        NodeDescriptors localNodeDescriptors = testLocalNodeDescriptors.getNodedescriptors();
+        testSubTlvs = localNodeDescriptors.getSubTlvs();
+        ListIterator<BgpValueType> subtlvlist1 = testSubTlvs.listIterator();
+
+        AutonomousSystemTlv testAutonomousSystemTlv = (AutonomousSystemTlv) subtlvlist1.next();
+
+        assertThat(testAutonomousSystemTlv.getAsNum(), is(2222));
+        assertThat(testAutonomousSystemTlv.getType(), is((short) 512));
+
+        BgpLSIdentifierTlv testBGPLSIdentifierTlv = (BgpLSIdentifierTlv) subtlvlist1.next();
+        assertThat(testBGPLSIdentifierTlv.getBgpLsIdentifier(), is(33686018));
+        assertThat(testBGPLSIdentifierTlv.getType(), is((short) 513));
+
+        IsIsNonPseudonode testIsIsNonPseudonode = (IsIsNonPseudonode) subtlvlist1.next();
+        byte[] expISONodeID = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
+        assertThat(testIsIsNonPseudonode.getISONodeID(), is(expISONodeID));
+        assertThat(testIsIsNonPseudonode.getType(), is((short) 515));
+    }
+
+    /**
+     * This test case checks update message with invalid mpreach packet.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest32() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, (byte) 0xbb, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
+                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
+                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
+                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
+                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
+                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
+                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
+                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
+                0x16, 0x16, 0x16, 0x16}; // prefix nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with invalid prefix nlri length in input.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest33() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xd6, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, (byte) 0xbb, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x90, 0x0e, 0x00, (byte) 0xa5, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x03, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x19, 0x21, 0x68,
+                0x07, 0x70, 0x01, 0x01, 0x09, 0x00, 0x05, 0x20,
+                (byte) 0xc0, (byte) 0xa8, 0x4d, 0x01, 0x00, 0x03, 0x00, 0x30,
+                0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x01, 0x00, 0x00, 0x1a, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00,
+                0x06, 0x19, 0x00, (byte) 0x95, 0x02, 0x50, 0x21, 0x01,
+                0x09, 0x00, 0x05, 0x20, 0x15, 0x15, 0x15, 0x15,
+                0x00, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+                0x1a, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08,
+                (byte) 0xae, 0x02, 0x01, 0x00, 0x04, 0x02, 0x02, 0x02,
+                0x02, 0x02, 0x03, 0x00, 0x06, 0x02, 0x20, 0x22,
+                0x02, 0x20, 0x22, 0x01, 0x09, 0x00, 0x05, 0x20,
+                0x16, 0x16, 0x16, 0x16}; // prefix nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    /**
+     * This test case checks update message with invalid link nlri length in input.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest34() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x83, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x68, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21}; //link nlri
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+    }
+
+    //Negative scenarios
+    /**
+     * Wrong length BgpAttrRouterIdV4.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest35() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x95,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7A, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
+                0x04, 0x04, 0x00, 0x06, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrRouterIdV4
+                0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x0a}; //BgpLinkAttrIGPMetric
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpHeader bgpHeader = new BgpHeader();
+        reader.readFrom(buffer, bgpHeader);
+    }
+
+    /**
+     * Wrong length BgpLinkAttrIGPMetric.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest36() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x95,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7A, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrRouterIdV4
+                0x04, 0x47, 0x00, 0x02, 0x00, 0x00, 0x0a}; //BgpLinkAttrIGPMetric
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpHeader bgpHeader = new BgpHeader();
+        reader.readFrom(buffer, bgpHeader);
+    }
+
+    /**
+     * Wrong length BgpPrefixAttrMetric.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest37() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                  0x04, (byte) 0x83, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00}; //BgpPrefixAttrMetric
+
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpHeader bgpHeader = new BgpHeader();
+        reader.readFrom(buffer, bgpHeader);
+    }
+
+    /**
+     * Wrong length BgpPrefixAttrMetric.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest38() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7b, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                  0x04, (byte) 0x83, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00}; //BgpPrefixAttrMetric
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpHeader bgpHeader = new BgpHeader();
+        reader.readFrom(buffer, bgpHeader);
+    }
+
+    /**
+     * Wrong length BgpPrefixAttrOpaqueData.
+     */
+    @Test(expected = BgpParseException.class)
+    public void bgpUpdateMessageTest39() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x96,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7B, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, (byte) 0x85, 0x00, 0x06, 0x0a, 0x0a, 0x0a, 0x0a}; //BgpPrefixAttrOpaqueData
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpHeader bgpHeader = new BgpHeader();
+        reader.readFrom(buffer, bgpHeader);
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrName.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest40() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x9A,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x7F, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x14,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, 0x4A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b}; //BgpLinkAttrName
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 154));
+
+        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
+        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};
+
+        while (listIterator1.hasNext()) {
+            IpPrefix testPrefixValue = listIterator1.next();
+            assertThat(testPrefixValue.prefixLength(), is((int) 24));
+            assertThat(testPrefixValue.address().toOctets(), is(prefix));
+        }
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
+        assertThat(mpReach.getType(), is((short) 14));
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        byte[] linkName = new byte[] {0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b };
+        assertThat(((BgpLinkAttrName) list.next()).attrLinkName(), is(linkName));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrIGPFlags.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest41() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0x93,
+                0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
+                0x00, 0x78, //path attribute len
+                0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
+                0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
+                (byte) 0x80, 0x1d, 0x0D,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
+                0x04, (byte) 0x80, 0x00, 0x01, (byte) 0xA0}; //BgpPrefixAttrIGPFlags
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 147));
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getIdentifier(), is((long) 0));
+        assertThat(testnlri.getNlriType(), is(nlriType));
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        BgpPrefixAttrIgpFlags obj = new BgpPrefixAttrIgpFlags(true, false, true, false);
+        assertThat(((BgpPrefixAttrIgpFlags) list.next()).equals(obj), is(true));
+    }
+
+    /**
+     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrExtRouteTag.
+     *
+     * @throws BgpParseException while parsing update message
+     */
+    @Test
+    public void bgpUpdateMessageTest42() throws BgpParseException {
+        byte[] updateMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, 0x00, (byte) 0xA2, 0x02, 0x00, 0x04,
+                0x18, 0x0a, 0x01, 0x01, 0x00, (byte) 0x87, 0x04, 0x01, 0x01, 0x00, //origin
+                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
+                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
+                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
+                0x04, 0x04, 0x00, 0x00, 0x01, 0x00, //reserved
+                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
+                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
+                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
+                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
+                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
+                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
+                0x00, (byte) 0x95, 0x02, 0x50, 0x21, (byte) 0x80, 0x1d, 0x1C,  //linkstate attr
+                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
+                0x04, (byte) 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, (byte) 0xBB, (byte) 0xE9, 0x0B,
+                0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x6E, 0x1B}; //BgpPrefixAttrExtRouteTag
+        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+        buffer.writeBytes(updateMsg);
+
+        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+        BgpMessage message = null;
+        BgpHeader bgpHeader = new BgpHeader();
+
+        message = reader.readFrom(buffer, bgpHeader);
+
+        assertThat(message, instanceOf(BgpUpdateMsg.class));
+        BgpUpdateMsg other = (BgpUpdateMsg) message;
+
+        byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                    (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertThat(other.getHeader().getMarker(), is(marker));
+        assertThat(other.getHeader().getType(), is((byte) 2));
+        assertThat(other.getHeader().getLength(), is((short) 162));
+
+        BgpValueType testPathAttribute = null;
+        Origin origin;
+        AsPath aspath;
+        Med med;
+        MpReachNlri mpReach;
+        LinkStateAttributes linkStateAttr;
+        List<BgpValueType> pathAttributeList = new LinkedList<>();
+        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
+        pathAttributeList = pathAttribute.pathAttributes();
+        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
+        ORIGINTYPE originValue = org.onosproject.bgpio.types.Origin.ORIGINTYPE.IGP;
+
+        testPathAttribute = listIterator.next();
+        origin = (Origin) testPathAttribute;
+        assertThat(origin.origin(), is(originValue));
+
+        testPathAttribute = listIterator.next();
+        aspath = (AsPath) testPathAttribute;
+        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
+        assertThat(listIterator2.next(), is((short) 65001));
+
+        testPathAttribute = listIterator.next();
+        med = (Med) testPathAttribute;
+        assertThat(med.med(), is(0));
+
+        testPathAttribute = listIterator.next();
+        mpReach = (MpReachNlri) testPathAttribute;
+
+        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
+        testMpReachNlri = mpReach.mpReachNlri();
+        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
+        BgpLSNlri testnlri =  list1.next();
+        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
+            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
+        assertThat(testnlri.getProtocolId(), is(protocolId));
+
+        testPathAttribute = listIterator.next();
+        linkStateAttr = (LinkStateAttributes) testPathAttribute;
+
+        assertThat(linkStateAttr.getType(), is((short) 29));
+        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
+        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
+        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
+        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
+        List<Long> extRouteTag = new LinkedList<>();
+        extRouteTag.add(45869323L);
+        extRouteTag.add(52456987L);
+        assertThat(((BgpPrefixAttrExtRouteTag) list.next()).pfxExtRouteTag(), is(extRouteTag));
+    }
+}
diff --git a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionTypeTest.java b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionTypeTest.java
index 2fb7635..6ce8a76 100644
--- a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionTypeTest.java
+++ b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionTypeTest.java
@@ -20,37 +20,20 @@
 import com.google.common.testing.EqualsTester;
 
 /**
- * Test for MPLS protocol mask attribute.
+ * Test for Protection Type attribute.
  */
 public class BgpLinkAttrProtectionTypeTest {
-    boolean bExtraTraffic = true;
-    boolean bUnprotected = true;
-    boolean bShared = true;
-    boolean bDedOneIstoOne = true;
-    boolean bDedOnePlusOne = true;
-    boolean bEnhanced = true;
+    private final byte linkProtectionType1 = 0x04;
+    private final byte linkProtectionType2 = 0x40;
 
-    boolean bExtraTraffic1 = false;
-    boolean bUnprotected1 = false;
-    boolean bShared1 = false;
-    boolean bDedOneIstoOne1 = false;
-    boolean bDedOnePlusOne1 = false;
-    boolean bEnhanced1 = false;
-
-    private final BgpLinkAttrProtectionType data = BgpLinkAttrProtectionType
-            .of(bExtraTraffic, bUnprotected, bShared, bDedOneIstoOne,
-                bDedOnePlusOne, bEnhanced);
-    private final BgpLinkAttrProtectionType sameAsData = BgpLinkAttrProtectionType
-            .of(bExtraTraffic, bUnprotected, bShared, bDedOneIstoOne,
-                bDedOnePlusOne, bEnhanced);
-    private final BgpLinkAttrProtectionType diffData = BgpLinkAttrProtectionType
-            .of(bExtraTraffic1, bUnprotected1, bShared1, bDedOneIstoOne1,
-                bDedOnePlusOne1, bEnhanced1);
+    private final BgpLinkAttrProtectionType attr1 = BgpLinkAttrProtectionType.of(linkProtectionType1);
+    private final BgpLinkAttrProtectionType sameAsAttr1 = BgpLinkAttrProtectionType.of(linkProtectionType1);
+    private final BgpLinkAttrProtectionType attr2 = BgpLinkAttrProtectionType.of(linkProtectionType2);
 
     @Test
-    public void basics() {
-
-        new EqualsTester().addEqualityGroup(data, sameAsData)
-        .addEqualityGroup(diffData).testEquals();
+    public void testEquality() {
+        new EqualsTester().addEqualityGroup(attr1, sameAsAttr1)
+        .addEqualityGroup(attr2)
+        .testEquals();
     }
 }
