ONOS-2739 - OSPF Basic Packet Structures , which includes encoding and decoding

Change-Id: Ic37fcf98dfb6c7a15a124b495aee8517a8df23c9
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/TlvHeader.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/TlvHeader.java
new file mode 100644
index 0000000..6eca17c
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/TlvHeader.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of a TLV header.
+ */
+public class TlvHeader {
+    private int tlvType;
+    private int tlvLength;
+
+    /**
+     * Gets TLV length.
+     *
+     * @return TLV length
+     */
+    public int tlvLength() {
+        return tlvLength;
+    }
+
+    /**
+     * Sets TLV length.
+     *
+     * @param tlvLength TLV length
+     */
+    public void setTlvLength(int tlvLength) {
+        this.tlvLength = tlvLength;
+    }
+
+    /**
+     * Gets TLV type.
+     *
+     * @return TLV type
+     */
+    public int tlvType() {
+        return tlvType;
+    }
+
+    /**
+     * Sets TLV type.
+     *
+     * @param tlvType TLV type
+     */
+    public void setTlvType(int tlvType) {
+        this.tlvType = tlvType;
+    }
+
+    /**
+     * Gets TLV header as bytes.
+     *
+     * @return TLV header as bytes
+     */
+    public byte[] getTlvHeaderAsByteArray() {
+        List<Byte> headerLst = new ArrayList();
+        headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.tlvType)));
+        headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.tlvLength)));
+        return Bytes.toArray(headerLst);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("tlvType", tlvType)
+                .add("tlvLength", tlvLength)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/AdministrativeGroup.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/AdministrativeGroup.java
new file mode 100644
index 0000000..375ea18
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/AdministrativeGroup.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+/**
+ * Representation of an administrative group value of link tlv of Traffic Engineering..
+ */
+public class AdministrativeGroup extends TlvHeader implements LinkSubType {
+
+    private int administrativeGroup;
+
+    /**
+     * Creates an administrative group instance.
+     *
+     * @param header Tlv Header instance
+     */
+    public AdministrativeGroup(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Gets administrative group value.
+     *
+     * @return administrative group value
+     */
+    public int administrativeGroup() {
+        return administrativeGroup;
+    }
+
+    /**
+     * Sets administrative group value.
+     *
+     * @param administrativeGroup value
+     */
+    public void setAdministrativeGroup(int administrativeGroup) {
+        this.administrativeGroup = administrativeGroup;
+    }
+
+    /**
+     * Gets administrative group value.
+     *
+     * @return administrativeGroup value
+     */
+    public int getAdministrativeGroupValue() {
+        return this.administrativeGroup;
+    }
+
+    /**
+     * Reads bytes from channel buffer.
+     *
+     * @param channelBuffer Channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        byte[] tempByteArray = new byte[tlvLength()];
+        channelBuffer.readBytes(tempByteArray, 0, tlvLength());
+        this.setAdministrativeGroup(OspfUtil.byteToInteger(tempByteArray));
+    }
+
+    /**
+     * Returns administrative group as byte array.
+     *
+     * @return administrative group instance as byte array
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets administrative group body as byte array.
+     *
+     * @return byte array of sub tlv administrative group
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+
+        byte[] linkSubTypeBody;
+        linkSubTypeBody = OspfUtil.convertToFourBytes(this.administrativeGroup);
+
+        return linkSubTypeBody;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("administrativeGroup", administrativeGroup)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkId.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkId.java
new file mode 100644
index 0000000..0ae22b7
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkId.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.exceptions.OspfErrorType;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+
+/**
+ * Representation of link id value of link tlv of Traffic Engineering.
+ */
+public class LinkId extends TlvHeader implements LinkSubType {
+    private static final Logger log =
+            LoggerFactory.getLogger(LinkId.class);
+    private String linkId;
+
+    /**
+     * Creates an instance of link id.
+     *
+     * @param header tlv header instance
+     */
+    public LinkId(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Sets link type.
+     *
+     * @param linkType link type value
+     */
+    public void setLinkId(String linkType) {
+        this.linkId = linkType;
+    }
+
+    /**
+     * Reads bytes from channel buffer.
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing packet
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        try {
+            byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
+            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
+            this.setLinkId(InetAddress.getByAddress(tempByteArray).getHostName());
+        } catch (Exception e) {
+            log.debug("Error::LinkId:: {}", e.getMessage());
+            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                         OspfErrorType.BAD_MESSAGE);
+        }
+    }
+
+    /**
+     * Returns instance as byte array.
+     *
+     * @return instance as bytes
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] asBytes() throws Exception {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets byte array of link id sub tlv body.
+     *
+     * @return gets the body as byte array
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() throws Exception {
+        byte[] linkSubTypeBody = null;
+        try {
+            linkSubTypeBody = InetAddress.getByName(this.linkId).getAddress();
+        } catch (Exception e) {
+            log.debug("Error::LinkId:: {}", e.getMessage());
+            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                         OspfErrorType.BAD_MESSAGE);
+        }
+        return linkSubTypeBody;
+    }
+
+    /**
+     * Returns this instance as string.
+     *
+     * @return this instance as string
+     */
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("linkId", linkId)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubType.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubType.java
new file mode 100644
index 0000000..1563dbd
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubType.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+/**
+ * Marker interface to represent TE Link sub types.
+ */
+public interface LinkSubType {
+}
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubTypes.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubTypes.java
new file mode 100644
index 0000000..95351fa
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkSubTypes.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+/**
+ * Representation of TE link sub types.
+ */
+public enum LinkSubTypes {
+    LINK_TYPE(1),
+    LINK_ID(2),
+    LOCAL_INTERFACE_IP_ADDRESS(3),
+    REMOTE_INTERFACE_IP_ADDRESS(4),
+    TRAFFIC_ENGINEERING_METRIC(5),
+    MAXIMUM_BANDWIDTH(6),
+    MAXIMUM_RESERVABLE_BANDWIDTH(7),
+    UNRESERVED_BANDWIDTH(8),
+    ADMINISTRATIVE_GROUP(9);
+
+    private int value;
+
+    /**
+     * Creates an instance of link sub types.
+     *
+     * @param value link sub type value
+     */
+    LinkSubTypes(int value) {
+        this.value = value;
+    }
+
+    /**
+     * Gets the link sub type value.
+     *
+     * @return link sub type value
+     */
+    public int value() {
+        return value;
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkType.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkType.java
new file mode 100644
index 0000000..8a13f83
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LinkType.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.exceptions.OspfErrorType;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Representation of link type TE value.
+ */
+public class LinkType extends TlvHeader implements LinkSubType {
+    private static final Logger log =
+            LoggerFactory.getLogger(LinkType.class);
+    private int linkType;
+
+    /**
+     * Creates link type instance .
+     */
+    public LinkType() {
+
+    }
+
+    /**
+     * Creates link type instance.
+     *
+     * @param header tlv header instance
+     */
+    public LinkType(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Sets link type.
+     *
+     * @param linkType value of link type
+     */
+    public void setLinkType(int linkType) {
+        this.linkType = linkType;
+    }
+
+    /**
+     * Reads from channel buffer.
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        try {
+            int len = channelBuffer.readableBytes();
+            byte[] tempByteArray = new byte[len];
+            channelBuffer.readBytes(tempByteArray, 0, len);
+            this.setLinkType(OspfUtil.byteToInteger(tempByteArray));
+        } catch (Exception e) {
+            log.debug("Error::LinkType:: {}", e.getMessage());
+            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                         OspfErrorType.BAD_MESSAGE);
+        }
+    }
+
+    /**
+     * Gets link subtype as byte array.
+     *
+     * @return byte array of link subtype
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+        return linkSubType;
+    }
+
+    /**
+     * Gets link subtype as bytes.
+     *
+     * @return byte array of link subtype
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+        byte[] linkSubTypeBody = new byte[4];
+        linkSubTypeBody[0] = (byte) this.linkType;
+        linkSubTypeBody[1] = 0;
+        linkSubTypeBody[2] = 0;
+        linkSubTypeBody[3] = 0;
+        return linkSubTypeBody;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("linkType", linkType)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LocalInterfaceIpAddress.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LocalInterfaceIpAddress.java
new file mode 100644
index 0000000..c8c584a
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/LocalInterfaceIpAddress.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.exceptions.OspfErrorType;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of local interface ip address TE value.
+ */
+public class LocalInterfaceIpAddress extends TlvHeader implements LinkSubType {
+    private static final Logger log =
+            LoggerFactory.getLogger(RemoteInterfaceIpAddress.class);
+    private List<String> localInterfaceIPAddress = new ArrayList<>();
+
+    /**
+     * Creates an instance of local interface ip address.
+     *
+     * @param header tlv header instance
+     */
+    public LocalInterfaceIpAddress(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Adds local interface ip address.
+     *
+     * @param localAddress ip address
+     */
+    public void addLocalInterfaceIPAddress(String localAddress) {
+        localInterfaceIPAddress.add(localAddress);
+    }
+
+    /**
+     * Gets local interface ip address.
+     *
+     * @return localAddress ip address
+     */
+    public List<String> getLocalInterfaceIPAddress() {
+        return localInterfaceIPAddress;
+    }
+
+    /**
+     * Reads bytes from channel buffer.
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        while (channelBuffer.readableBytes() >= OspfUtil.FOUR_BYTES) {
+            try {
+                byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
+                channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
+                this.addLocalInterfaceIPAddress(InetAddress.getByAddress(tempByteArray).getHostName());
+            } catch (Exception e) {
+                log.debug("Error::readFrom:: {}", e.getMessage());
+                throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                             OspfErrorType.BAD_MESSAGE);
+            }
+        }
+    }
+
+    /**
+     * Gets local interface ip address as byte array.
+     *
+     * @return local interface ip address as byte array
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] asBytes() throws Exception {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets byte array of local interface ip address.
+     *
+     * @return byte array of local interface ip address
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() throws Exception {
+
+        List<Byte> linkSubTypeBody = new ArrayList<>();
+
+        for (String remoteAddress : this.localInterfaceIPAddress) {
+            try {
+                linkSubTypeBody.addAll(Bytes.asList(InetAddress.getByName(remoteAddress).getAddress()));
+            } catch (Exception e) {
+                log.debug("Error::getLinkSubTypeTlvBodyAsByteArray:: {}", e.getMessage());
+                throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                             OspfErrorType.BAD_MESSAGE);
+            }
+        }
+
+        return Bytes.toArray(linkSubTypeBody);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("localInterfaceIPAddress", localInterfaceIPAddress)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumBandwidth.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumBandwidth.java
new file mode 100644
index 0000000..83dcbe9
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumBandwidth.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+/**
+ * Representation of maximum bandwidth TE value.
+ */
+public class MaximumBandwidth extends TlvHeader implements LinkSubType {
+    private float maximumBandwidth;
+
+    /**
+     * Creates an instance of maximum bandwidth.
+     *
+     * @param header tlv header instance
+     */
+    public MaximumBandwidth(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Sets value of maximum bandwidth.
+     *
+     * @param maximumBandwidth value of maximum bandwidth
+     */
+    public void setMaximumBandwidth(float maximumBandwidth) {
+        this.maximumBandwidth = maximumBandwidth;
+    }
+
+    /**
+     * Gets value of maximum bandwidth.
+     *
+     * @return maximumBandwidth value of maximum bandwidth
+     */
+    public float getMaximumBandwidthValue() {
+        return this.maximumBandwidth;
+    }
+
+    /**
+     * Reads bytes from channel buffer.
+     *
+     * @param channelBuffer channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        byte[] tempByteArray = new byte[tlvLength()];
+        channelBuffer.readBytes(tempByteArray, 0, tlvLength());
+        int maxBandwidth = (OspfUtil.byteToInteger(tempByteArray));
+        this.setMaximumBandwidth(Float.intBitsToFloat(maxBandwidth));
+    }
+
+    /**
+     * Gets byte array of maximum bandwidth sub tlv.
+     *
+     * @return byte array of maximum bandwidth sub tlv
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets maximum bandwidth sub tlv byte array.
+     *
+     * @return byte array of maximum bandwidth sub tlv
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+        byte[] linkSubTypeBody;
+        linkSubTypeBody = OspfUtil.convertToFourBytes(Float.floatToIntBits(this.maximumBandwidth));
+        return linkSubTypeBody;
+    }
+
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("maximumBandwidth", maximumBandwidth)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumReservableBandwidth.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumReservableBandwidth.java
new file mode 100644
index 0000000..c59712e
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/MaximumReservableBandwidth.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+/**
+ * Representation of maximum reservable bandwidth TE value.
+ */
+public class MaximumReservableBandwidth extends TlvHeader implements LinkSubType {
+    private float maximumReservableBandwidth;
+
+    /**
+     * Creates an instance of maximum reservable bandwidth.
+     *
+     * @param header tlv header
+     */
+    public MaximumReservableBandwidth(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Sets value of maximum reversible bandwidth.
+     *
+     * @param maximumBandwidth maximum reversible bandwidth
+     */
+    public void setMaximumBandwidth(float maximumBandwidth) {
+        this.maximumReservableBandwidth = maximumBandwidth;
+    }
+
+    /**
+     * Gets value of maximum reversible bandwidth.
+     *
+     * @return maximumBandwidth maximum reversible bandwidth
+     */
+    public float getMaximumBandwidthValue() {
+        return this.maximumReservableBandwidth;
+    }
+
+    /**
+     * Reads bytes from channel buffer.
+     *
+     * @param channelBuffer channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        byte[] tempByteArray = new byte[tlvLength()];
+        channelBuffer.readBytes(tempByteArray, 0, tlvLength());
+        int maxBandwidth = (OspfUtil.byteToInteger(tempByteArray));
+        this.setMaximumBandwidth(Float.intBitsToFloat(maxBandwidth));
+    }
+
+    /**
+     * Returns byte array of maximum reservable bandwidth.
+     *
+     * @return byte array of maximum reservable bandwidth
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinksubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+        return linkSubType;
+
+    }
+
+    /**
+     * Gets maximum reservable bandwidth sub tlv body as byte array.
+     *
+     * @return byte of maximum reservable bandwidth sub tlv body
+     */
+    public byte[] getLinksubTypeTlvBodyAsByteArray() {
+        byte[] linkSubTypeBody;
+        linkSubTypeBody = OspfUtil.convertToFourBytes(Float.floatToIntBits(this.maximumReservableBandwidth));
+        return linkSubTypeBody;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("maximumReservableBandwidth", maximumReservableBandwidth)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/RemoteInterfaceIpAddress.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/RemoteInterfaceIpAddress.java
new file mode 100644
index 0000000..d6a6725
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/RemoteInterfaceIpAddress.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.exceptions.OspfErrorType;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of remote interface ip address TE value.
+ */
+public class RemoteInterfaceIpAddress extends TlvHeader implements LinkSubType {
+    private static final Logger log =
+            LoggerFactory.getLogger(RemoteInterfaceIpAddress.class);
+    private List<String> remoteInterfaceAddress = new ArrayList<>();
+
+    /**
+     * Creates an instance of remote interface ip address.
+     *
+     * @param header tlv header instance
+     */
+    public RemoteInterfaceIpAddress(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Adds remote interface ip address.
+     *
+     * @param remoteAddress ip address
+     */
+    public void addRemoteInterfaceAddress(String remoteAddress) {
+        remoteInterfaceAddress.add(remoteAddress);
+    }
+
+    /**
+     * Gets remote interface ip address.
+     *
+     * @return remoteAddress ip address
+     */
+    public List<String> getRemoteInterfaceAddress() {
+        return remoteInterfaceAddress;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing packet
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        while (channelBuffer.readableBytes() >= OspfUtil.FOUR_BYTES) {
+            try {
+                byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
+                channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
+                this.addRemoteInterfaceAddress(InetAddress.getByAddress(tempByteArray).getHostName());
+            } catch (Exception e) {
+                log.debug("Error::RemoteInterfaceIPAddress:: {}", e.getMessage());
+                throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                             OspfErrorType.BAD_MESSAGE);
+            }
+        }
+    }
+
+    /**
+     * Gets byte array of remote interface ip address .
+     *
+     * @return byte array of remote interface ip address
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] asBytes() throws Exception {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets byte array of remote interface ip address.
+     *
+     * @return byte array of remote interface ip address
+     * @throws Exception might throws exception while parsing packet
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() throws Exception {
+        List<Byte> linkSubTypeBody = new ArrayList<>();
+
+        for (String remoteAddress : this.remoteInterfaceAddress) {
+            try {
+                linkSubTypeBody.addAll(Bytes.asList(InetAddress.getByName(remoteAddress).getAddress()));
+            } catch (Exception e) {
+                log.debug("Error::RemoteInterfaceIPAddress:: {}", e.getMessage());
+                throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                             OspfErrorType.BAD_MESSAGE);
+            }
+        }
+
+        return Bytes.toArray(linkSubTypeBody);
+    }
+
+    /**
+     * Returns instance as string.
+     *
+     * @return instance as string
+     */
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("RemoteInterfaceIPAddress", remoteInterfaceAddress)
+                .toString();
+    }
+
+}
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/TrafficEngineeringMetric.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/TrafficEngineeringMetric.java
new file mode 100644
index 0000000..176604f
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/TrafficEngineeringMetric.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+/**
+ * Representation of traffic engineering metric TE value.
+ */
+public class TrafficEngineeringMetric extends TlvHeader implements LinkSubType {
+    private long trafficEngineeringMetric;
+
+    /**
+     * Creates an instance of traffic engineering metric .
+     *
+     * @param header tlv header instance
+     */
+    public TrafficEngineeringMetric(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Sets TE metric value.
+     *
+     * @param trafficEngineeringMetric value of trafficEngineeringMetric
+     */
+    public void setTrafficEngineeringMetric(long trafficEngineeringMetric) {
+        this.trafficEngineeringMetric = trafficEngineeringMetric;
+    }
+
+    /**
+     * Gets TE metric value.
+     *
+     * @return value of traffic engineering metric
+     */
+    public long getTrafficEngineeringMetricValue() {
+        return this.trafficEngineeringMetric;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        byte[] tempByteArray = new byte[tlvLength()];
+        channelBuffer.readBytes(tempByteArray, 0, tlvLength());
+        this.setTrafficEngineeringMetric(OspfUtil.byteToLong(tempByteArray));
+    }
+
+    /**
+     * Gets instance as byte array.
+     *
+     * @return instance as byte array
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets trafficEngineeringMetric as byte array .
+     *
+     * @return byte array of trafficEngineeringMetric
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+
+        byte[] linkSubTypeBody;
+        linkSubTypeBody = OspfUtil.convertToFourBytes(this.trafficEngineeringMetric);
+
+        return linkSubTypeBody;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("trafficEngineeringMetric", trafficEngineeringMetric)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnknownLinkSubType.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnknownLinkSubType.java
new file mode 100644
index 0000000..b2c49fb
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnknownLinkSubType.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+
+/**
+ * Representation of an unknown or experimental TE value.
+ */
+public class UnknownLinkSubType extends TlvHeader implements LinkSubType {
+
+    private byte[] value;
+
+    /**
+     * Creates an instance of this.
+     *
+     * @param header tlv header
+     */
+    public UnknownLinkSubType(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Gets the unknown subtype value .
+     *
+     * @return unknown subtype value
+     */
+    public byte[] value() {
+        return value;
+    }
+
+    /**
+     * Sets unknown subtype value.
+     *
+     * @param value unknown subtype value.
+     */
+    public void setValue(byte[] value) {
+        this.value = value;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        byte[] tempByteArray = new byte[tlvLength()];
+        channelBuffer.readBytes(tempByteArray, 0, tlvLength());
+        this.setValue(tempByteArray);
+    }
+
+    /**
+     * Returns instance as byte array.
+     *
+     * @return instance as byte array
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+        return linkSubType;
+
+    }
+
+    /**
+     * Gets instance body as byte array.
+     *
+     * @return instance body as byte array
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("value", value)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnreservedBandwidth.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnreservedBandwidth.java
new file mode 100644
index 0000000..11b1429
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/UnreservedBandwidth.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.linksubtype;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of an unreserved band width TE value.
+ */
+public class UnreservedBandwidth extends TlvHeader implements LinkSubType {
+    private List<Float> unReservedBandwidth = new ArrayList<>();
+
+    /**
+     * Creates an instance of unreserved band width.
+     *
+     * @param header tlv header instance
+     */
+    public UnreservedBandwidth(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Adds value of un reserved bandwidth .
+     *
+     * @param unreservedBandwidth value of un reserved bandwidth
+     */
+    public void addUnReservedBandwidth(float unreservedBandwidth) {
+        this.unReservedBandwidth.add(unreservedBandwidth);
+    }
+
+    /**
+     * Gets list of un reserved bandwidth .
+     *
+     * @return List of un reserved bandwidth
+     */
+    public List<Float> getUnReservedBandwidthValue() {
+        return this.unReservedBandwidth;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     */
+    public void readFrom(ChannelBuffer channelBuffer) {
+        while (channelBuffer.readableBytes() >= OspfUtil.FOUR_BYTES) {
+            int maxReversibleBandwidth = channelBuffer.readInt();
+            this.addUnReservedBandwidth(Float.intBitsToFloat(maxReversibleBandwidth));
+        }
+    }
+
+    /**
+     * Gets instance as byte array.
+     *
+     * @return instance as byte array
+     */
+    public byte[] asBytes() {
+        byte[] linkSubType = null;
+
+        byte[] linkSubTlvHeader = getTlvHeaderAsByteArray();
+        byte[] linkSubTlvBody = getLinkSubTypeTlvBodyAsByteArray();
+        linkSubType = Bytes.concat(linkSubTlvHeader, linkSubTlvBody);
+
+        return linkSubType;
+    }
+
+    /**
+     * Gets unreserved bandwidth as byte array.
+     *
+     * @return unreserved bandwidth as byte array
+     */
+    public byte[] getLinkSubTypeTlvBodyAsByteArray() {
+        List<Byte> linkSubTypeBody = new ArrayList<>();
+        if (this.unReservedBandwidth.size() < 8) {
+            int size = OspfUtil.EIGHT_BYTES - this.unReservedBandwidth.size();
+            for (int i = 0; i < size; i++) {
+                linkSubTypeBody.addAll(Bytes.asList(OspfUtil.convertToFourBytes(OspfParameters.INITIAL_BANDWIDTH)));
+            }
+        }
+        for (Float unreservedBandwidth : this.unReservedBandwidth) {
+            int unresBandwidth = Float.floatToIntBits(unreservedBandwidth);
+            linkSubTypeBody.addAll(Bytes.asList(OspfUtil.convertToFourBytes(unresBandwidth)));
+        }
+
+        return Bytes.toArray(linkSubTypeBody);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("unReservedBandwidth", unReservedBandwidth)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/package-info.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/package-info.java
new file mode 100644
index 0000000..01c938d
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/linksubtype/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 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.
+ */
+
+/**
+ * Implementation of the ospf TE link types.
+ */
+package org.onosproject.ospf.protocol.lsa.linksubtype;
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java
new file mode 100644
index 0000000..aaf66da
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.tlvtypes;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.lsa.linksubtype.AdministrativeGroup;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkId;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkSubType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkSubTypes;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LocalInterfaceIpAddress;
+import org.onosproject.ospf.protocol.lsa.linksubtype.MaximumBandwidth;
+import org.onosproject.ospf.protocol.lsa.linksubtype.MaximumReservableBandwidth;
+import org.onosproject.ospf.protocol.lsa.linksubtype.RemoteInterfaceIpAddress;
+import org.onosproject.ospf.protocol.lsa.linksubtype.TrafficEngineeringMetric;
+import org.onosproject.ospf.protocol.lsa.linksubtype.UnknownLinkSubType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.UnreservedBandwidth;
+import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of an OSPF Opaque link tlv.
+ */
+public class LinkTlv extends TlvHeader implements TopLevelTlv {
+    private List<LinkSubType> subTlv = new ArrayList<>();
+
+    /**
+     * Creates an instance of link tlv.
+     *
+     * @param header tlv header
+     */
+    public LinkTlv(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Gets sub tlv lists.
+     *
+     * @return sub tlv lists
+     */
+    public List<LinkSubType> subTlvList() {
+        return this.subTlv;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing packet
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        while (channelBuffer.readableBytes() > 0) {
+            TlvHeader tlvHeader = new TlvHeader();
+            tlvHeader.setTlvType(channelBuffer.readUnsignedShort());
+            tlvHeader.setTlvLength(channelBuffer.readUnsignedShort());
+
+            if (LinkSubTypes.LINK_TYPE.value() == tlvHeader.tlvType()) {
+                LinkType linktype = new LinkType(tlvHeader);
+                linktype.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(linktype);
+                if (tlvHeader.tlvLength() < OspfUtil.FOUR_BYTES) {
+                    int readerIndex = channelBuffer.readerIndex() + (OspfUtil.FOUR_BYTES - tlvHeader.tlvLength());
+                    channelBuffer.readerIndex(readerIndex);
+                }
+            } else if (LinkSubTypes.LINK_ID.value() == tlvHeader.tlvType()) {
+                LinkId linkId = new LinkId(tlvHeader);
+                linkId.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(linkId);
+            } else if (LinkSubTypes.LOCAL_INTERFACE_IP_ADDRESS.value() == tlvHeader.tlvType()) {
+                LocalInterfaceIpAddress localInterfaceIpAddress = new LocalInterfaceIpAddress(tlvHeader);
+                localInterfaceIpAddress.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(localInterfaceIpAddress);
+            } else if (LinkSubTypes.REMOTE_INTERFACE_IP_ADDRESS.value() == tlvHeader.tlvType()) {
+                RemoteInterfaceIpAddress remoteInterfaceIpAddress = new RemoteInterfaceIpAddress(tlvHeader);
+                remoteInterfaceIpAddress.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(remoteInterfaceIpAddress);
+            } else if (LinkSubTypes.TRAFFIC_ENGINEERING_METRIC.value() == tlvHeader.tlvType()) {
+                TrafficEngineeringMetric trafficEngineeringMetric = new TrafficEngineeringMetric(tlvHeader);
+                trafficEngineeringMetric.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(trafficEngineeringMetric);
+            } else if (LinkSubTypes.MAXIMUM_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                MaximumBandwidth maximumBandwidth = new MaximumBandwidth(tlvHeader);
+                maximumBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(maximumBandwidth);
+            } else if (LinkSubTypes.MAXIMUM_RESERVABLE_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                MaximumReservableBandwidth maximumReservableBandwidth = new MaximumReservableBandwidth(tlvHeader);
+                maximumReservableBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(maximumReservableBandwidth);
+            } else if (LinkSubTypes.UNRESERVED_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                UnreservedBandwidth unreservedBandwidth = new UnreservedBandwidth(tlvHeader);
+                unreservedBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(unreservedBandwidth);
+            } else if (LinkSubTypes.ADMINISTRATIVE_GROUP.value() == tlvHeader.tlvType()) {
+                AdministrativeGroup administrativeGroup = new AdministrativeGroup(tlvHeader);
+                administrativeGroup.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(administrativeGroup);
+            } else {
+                UnknownLinkSubType unknownLinkSubType = new UnknownLinkSubType(tlvHeader);
+                unknownLinkSubType.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(unknownLinkSubType);
+            }
+        }
+    }
+
+    /**
+     * Gets link tlv as byte array.
+     *
+     * @return link tlv as byte array
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public byte[] asBytes() throws Exception {
+        byte[] lsaMessage = null;
+
+        byte[] tlvHeader = getTlvHeaderAsByteArray();
+        byte[] tlvBody = getTlvBodyAsByteArray();
+        lsaMessage = Bytes.concat(tlvHeader, tlvBody);
+
+        return lsaMessage;
+    }
+
+    /**
+     * Gets tlv body as byte array.
+     *
+     * @return tlv body as byte array
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public byte[] getTlvBodyAsByteArray() throws Exception {
+
+        List<Byte> bodyLst = new ArrayList<>();
+        for (LinkSubType tlv : subTlv) {
+            //Check the type of tlv and build bytes accordingly
+            if (tlv instanceof LinkType) {
+                LinkType linkType = (LinkType) tlv;
+                bodyLst.addAll(Bytes.asList(linkType.asBytes()));
+            } else if (tlv instanceof LinkId) {
+                LinkId linkId = (LinkId) tlv;
+                bodyLst.addAll(Bytes.asList(linkId.asBytes()));
+            } else if (tlv instanceof LocalInterfaceIpAddress) {
+                LocalInterfaceIpAddress localInterfaceIpAddress = (LocalInterfaceIpAddress) tlv;
+                bodyLst.addAll(Bytes.asList(localInterfaceIpAddress.asBytes()));
+            } else if (tlv instanceof RemoteInterfaceIpAddress) {
+                RemoteInterfaceIpAddress remoteInterfaceIpAddress = (RemoteInterfaceIpAddress) tlv;
+                bodyLst.addAll(Bytes.asList(remoteInterfaceIpAddress.asBytes()));
+            } else if (tlv instanceof TrafficEngineeringMetric) {
+                TrafficEngineeringMetric trafficEngineeringMetric = (TrafficEngineeringMetric) tlv;
+                bodyLst.addAll(Bytes.asList(trafficEngineeringMetric.asBytes()));
+            } else if (tlv instanceof MaximumBandwidth) {
+                MaximumBandwidth maximumBandwidth = (MaximumBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(maximumBandwidth.asBytes()));
+            } else if (tlv instanceof MaximumReservableBandwidth) {
+                MaximumReservableBandwidth maximumReservableBandwidth = (MaximumReservableBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(maximumReservableBandwidth.asBytes()));
+            } else if (tlv instanceof UnreservedBandwidth) {
+                UnreservedBandwidth unreservedBandwidth = (UnreservedBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(unreservedBandwidth.asBytes()));
+            } else if (tlv instanceof AdministrativeGroup) {
+                AdministrativeGroup administrativeGroup = (AdministrativeGroup) tlv;
+                bodyLst.addAll(Bytes.asList(administrativeGroup.asBytes()));
+            } else {
+                UnknownLinkSubType unknownLinkSubType = (UnknownLinkSubType) tlv;
+                bodyLst.addAll(Bytes.asList(unknownLinkSubType.asBytes()));
+            }
+        }
+        return Bytes.toArray(bodyLst);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("subTlv", subTlv)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/OpaqueTopLevelTlvTypes.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/OpaqueTopLevelTlvTypes.java
new file mode 100644
index 0000000..2337b50
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/OpaqueTopLevelTlvTypes.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.tlvtypes;
+
+/**
+ * Representation of an OSPF Opaque top level tlv types.
+ */
+public enum OpaqueTopLevelTlvTypes {
+
+    ROUTER(1),
+    LINK(2);
+
+    private int value;
+
+    /**
+     * Creates an instance of Opaque top level tlv types.
+     *
+     * @param value
+     */
+    OpaqueTopLevelTlvTypes(int value) {
+        this.value = value;
+    }
+
+    /**
+     * Gets the tlv type value.
+     *
+     * @return tlv type value
+     */
+    public int value() {
+        return value;
+    }
+
+}
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/RouterTlv.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/RouterTlv.java
new file mode 100644
index 0000000..6c5d7a2
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/RouterTlv.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.tlvtypes;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.exceptions.OspfErrorType;
+import org.onosproject.ospf.exceptions.OspfParseException;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of an OSPF Opaque router tlv.
+ */
+public class RouterTlv extends TlvHeader implements TopLevelTlv {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(RouterTlv.class);
+    private Ip4Address routerAddress;
+
+    /**
+     * Creates an instance of Opaque router tlv.
+     *
+     * @param header tlv header
+     */
+    public RouterTlv(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Gets router address.
+     *
+     * @return router address
+     */
+    public Ip4Address routerAddress() {
+        return routerAddress;
+    }
+
+    /**
+     * Sets router address.
+     *
+     * @param routerAddress router address.
+     */
+    public void setRouterAddress(Ip4Address routerAddress) {
+        this.routerAddress = routerAddress;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        try {
+            byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
+            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
+            this.setRouterAddress(Ip4Address.valueOf(tempByteArray));
+        } catch (Exception e) {
+            log.debug("Error::RouterTLV:: {}", e.getMessage());
+            throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
+                                         OspfErrorType.BAD_MESSAGE);
+        }
+    }
+
+    /**
+     * Gets router tlv as byte array.
+     *
+     * @return router tlv as byte array
+     */
+    public byte[] asBytes() {
+        byte[] lsaMessage = null;
+
+        byte[] tlvHeader = getTlvHeaderAsByteArray();
+        byte[] tlvBody = getTlvBodyAsByteArray();
+        lsaMessage = Bytes.concat(tlvHeader, tlvBody);
+
+        return lsaMessage;
+    }
+
+    /**
+     * Gets tlv body as byte array.
+     *
+     * @return tlv body as byte array
+     */
+    public byte[] getTlvBodyAsByteArray() {
+        List<Byte> bodyLst = new ArrayList<>();
+        bodyLst.addAll(Bytes.asList(this.routerAddress().toOctets()));
+
+        return Bytes.toArray(bodyLst);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("routerAddress", routerAddress)
+                .toString();
+    }
+}
+
+
diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/package-info.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/package-info.java
new file mode 100644
index 0000000..0383e96
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 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.
+ */
+
+/**
+ * Implementation of the OSPF Opaque Tlv Types.
+ */
+package org.onosproject.ospf.protocol.lsa.tlvtypes;
\ No newline at end of file