Adding BGP provider code to support EVPN

Change-Id: Ic5508749b64a47a70f1aabd9324e9f89e85fa39f
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java
new file mode 100755
index 0000000..212b921
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpEvpnNlri.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.protocol;
+
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriData;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType;
+import org.onosproject.bgpio.types.BgpValueType;
+
+/**
+ * Abstraction of an entity providing BGP-EVPN NLRI.
+ */
+public interface BgpEvpnNlri extends BgpValueType {
+
+    /**
+     * Returns route type in Nlri.
+     *
+     * @return route type in Nlri
+     */
+    BgpEvpnRouteType getRouteType();
+
+    /**
+     * Returns route type specific Nlri.
+     *
+     * @return route type in Nlri
+     */
+    BgpEvpnNlriData getNlri();
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
index 708bc06..4346b86 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java
@@ -148,6 +148,16 @@
          */
         Builder setFlowSpecRpdCapabilityTlv(boolean isFlowSpecRpdCapabilitySet);
 
+        /**
+         * Sets Evpn capability and return its builder.
+         *
+         * @param isEvpnCapabilitySet boolean value to know whether evpn
+         *            capability is set or not
+         *
+         * @return builder by setting capabilities
+         */
+        Builder setEvpnCapabilityTlv(boolean isEvpnCapabilitySet);
+
         @Override
         Builder setHeader(BgpHeader bgpMsgHeader);
     }
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java
new file mode 100755
index 0000000..e91e94a
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriData.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.protocol.evpn;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+public interface BgpEvpnNlriData {
+
+    /**
+     * Returns the Type of RouteTypeSpefic.
+     *
+     * @return short value of type
+     */
+    BgpEvpnRouteType getType();
+
+    /**
+     * Writes the byte Stream of BGP Message to channel buffer.
+     *
+     * @param cb channel buffer
+     * @return length written to channel buffer
+     */
+    int write(ChannelBuffer cb);
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java
new file mode 100755
index 0000000..cfe0530
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnNlriImpl.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.protocol.evpn;
+
+import com.google.common.base.MoreObjects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
+import org.onosproject.bgpio.types.BgpErrorType;
+import org.onosproject.bgpio.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of Evpn NLRI.
+ */
+public class BgpEvpnNlriImpl implements BgpEvpnNlri {
+
+    /*
+     * REFERENCE : RFC 7432 BGP MPLS-Based Ethernet VPN
+                 +-----------------------------------+
+                 |    Route Type (1 octet)           |
+                 +-----------------------------------+
+                 |     Length (1 octet)              |
+                 +-----------------------------------+
+                 | Route Type specific (variable)    |
+                 +-----------------------------------+
+
+                Figure : The format of the EVPN NLRI
+     */
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(BgpEvpnNlriImpl.class);
+
+    // total length of route type and length
+    public static final short TYPE_AND_LEN = 2;
+    private byte routeType;
+    private BgpEvpnNlriData routeTypeSpec;
+
+    /**
+     * Resets parameters.
+     */
+    public BgpEvpnNlriImpl() {
+        this.routeType = Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT;
+        this.routeTypeSpec = null;
+
+    }
+
+    /**
+     * Constructor to initialize parameters for BGP EvpnNlri.
+     *
+     * @param routeType       route Type
+     * @param routeTypeSpefic route type specific
+     */
+    public BgpEvpnNlriImpl(byte routeType, BgpEvpnNlriData routeTypeSpefic) {
+        this.routeType = routeType;
+        this.routeTypeSpec = routeTypeSpefic;
+    }
+
+    /**
+     * Reads from channelBuffer and parses Evpn Nlri.
+     *
+     * @param cb ChannelBuffer
+     * @return object of BgpEvpnNlriVer4
+     * @throws BgpParseException while parsing Bgp Evpn Nlri
+     */
+    public static BgpEvpnNlriImpl read(ChannelBuffer cb)
+            throws BgpParseException {
+
+        BgpEvpnNlriData routeNlri = null;
+
+        if (cb.readableBytes() > 0) {
+            ChannelBuffer tempBuf = cb.copy();
+            byte type = cb.readByte();
+            byte length = cb.readByte();
+            if (cb.readableBytes() < length) {
+                throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
+                                            BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+                                            tempBuf.readBytes(cb.readableBytes()
+                                                                      + TYPE_AND_LEN));
+            }
+            ChannelBuffer tempCb = cb.readBytes(length);
+            switch (type) {
+                case BgpEvpnRouteType2Nlri.TYPE:
+                    routeNlri = BgpEvpnRouteType2Nlri.read(tempCb);
+                    break;
+                default:
+                    log.info("Discarding, EVPN route type {}", type);
+                    throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
+                                                BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE, null);
+                    //        break;
+            }
+            return new BgpEvpnNlriImpl(type, routeNlri);
+        } else {
+            return new BgpEvpnNlriImpl();
+        }
+
+    }
+
+    @Override
+    public BgpEvpnNlriData getNlri() {
+        return routeTypeSpec;
+    }
+
+    @Override
+    public BgpEvpnRouteType getRouteType() {
+        switch (routeType) {
+            case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+                return BgpEvpnRouteType.ETHERNET_AUTO_DISCOVERY;
+            case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+                return BgpEvpnRouteType.MAC_IP_ADVERTISEMENT;
+            case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+                return BgpEvpnRouteType.INCLUSIVE_MULTICASE_ETHERNET;
+            case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+                return BgpEvpnRouteType.ETHERNET_SEGMENT;
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).omitNullValues()
+                .add("routeType", routeType)
+                .add("routeTypeSpefic ", routeTypeSpec).toString();
+    }
+
+    @Override
+    public short getType() {
+        return routeType;
+    }
+
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeByte(routeType);
+        int iSpecStartIndex = cb.writerIndex();
+        cb.writeByte(0);
+        switch (routeType) {
+            case BgpEvpnRouteType2Nlri.TYPE:
+                ((BgpEvpnRouteType2Nlri) routeTypeSpec).write(cb);
+                break;
+            default:
+                break;
+        }
+        cb.setByte(iSpecStartIndex,
+                   (short) (cb.writerIndex() - iSpecStartIndex + 1));
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    @Override
+    public int compareTo(Object o) {
+        return 0;
+    }
+
+
+}
+
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java
new file mode 100755
index 0000000..6b919c3
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.protocol.evpn;
+
+/**
+ * Enum to provide EVPN RouteType.
+ */
+public enum BgpEvpnRouteType {
+    ETHERNET_AUTO_DISCOVERY(1), MAC_IP_ADVERTISEMENT(2),
+    INCLUSIVE_MULTICASE_ETHERNET(3), ETHERNET_SEGMENT(4);
+    int value;
+
+    /**
+     * Assign val with the value as the route type.
+     *
+     * @param val route type
+     */
+    BgpEvpnRouteType(int val) {
+        value = val;
+    }
+
+    /**
+     * Returns value of route type.
+     *
+     * @return route type
+     */
+    public byte getType() {
+        return (byte) value;
+    }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java
new file mode 100755
index 0000000..76fcbce
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/BgpEvpnRouteType2Nlri.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.protocol.evpn;
+
+import com.google.common.base.MoreObjects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onlab.packet.MacAddress;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.types.BgpEvpnEsi;
+import org.onosproject.bgpio.types.BgpEvpnLabel;
+import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.util.Constants;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+
+public class BgpEvpnRouteType2Nlri implements BgpEvpnNlriData {
+
+    /*
+     * REFERENCE : RFC 7432 BGP MPLS-Based Ethernet VPN
+         +---------------------------------------+
+         | RD (8 octets) |
+         +---------------------------------------+
+         |Ethernet Segment Identifier (10 octets)|
+         +---------------------------------------+
+         | Ethernet Tag ID (4 octets) |
+         +---------------------------------------+
+         | MAC Address Length (1 octet) |
+         +---------------------------------------+
+         | MAC Address (6 octets) |
+         +---------------------------------------+
+         | IP Address Length (1 octet) |
+         +---------------------------------------+
+         | IP Address (0, 4, or 16 octets) |
+         +---------------------------------------+
+         | MPLS Label1 (3 octets) |
+         +---------------------------------------+
+         | MPLS Label2 (0 or 3 octets) |
+         +---------------------------------------+
+
+      Figure : A MAC/IP Advertisement route type specific EVPN NLRI
+
+     */
+
+    public static final short TYPE = Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT;
+    protected static final Logger log = LoggerFactory.getLogger(BgpEvpnRouteType2Nlri.class);
+    // unit of length is bit
+    public static final short IPV4_ADDRESS_LENGTH = 32;
+    public static final short MAC_ADDRESS_LENGTH = 48;
+    private RouteDistinguisher rd;
+    private BgpEvpnEsi esi;
+    private int ethernetTagID;
+    private byte macAddressLength;
+    private MacAddress macAddress;
+    private byte ipAddressLength;
+    private InetAddress ipAddress;
+    private BgpEvpnLabel mplsLabel1;
+    private BgpEvpnLabel mplsLabel2;
+
+    /**
+     * Resets parameters.
+     */
+    public BgpEvpnRouteType2Nlri() {
+        this.rd = null;
+        this.esi = null;
+        this.ethernetTagID = 0;
+        this.macAddressLength = 0;
+        this.macAddress = null;
+        this.ipAddressLength = 0;
+        this.ipAddress = null;
+        this.mplsLabel1 = null;
+        this.mplsLabel2 = null;
+    }
+
+    /**
+     * Creates the Evpn route type 2 route.
+     *
+     * @param rd            route distinguisher
+     * @param esi           esi
+     * @param ethernetTagID ethernet tag id
+     * @param macAddress    mac
+     * @param ipAddress     ip
+     * @param mplsLabel1    label
+     * @param mplsLabel2    label
+     */
+    public BgpEvpnRouteType2Nlri(RouteDistinguisher rd,
+                                 BgpEvpnEsi esi,
+                                 int ethernetTagID, MacAddress macAddress,
+                                 InetAddress ipAddress, BgpEvpnLabel mplsLabel1,
+                                 BgpEvpnLabel mplsLabel2) {
+        this.rd = rd;
+        this.esi = esi;
+        this.ethernetTagID = ethernetTagID;
+        this.macAddressLength = MAC_ADDRESS_LENGTH;
+        this.macAddress = macAddress;
+        if (ipAddress != null) {
+            this.ipAddressLength = IPV4_ADDRESS_LENGTH;
+            this.ipAddress = ipAddress;
+        } else {
+            this.ipAddressLength = 0;
+            this.ipAddress = null;
+        }
+        this.mplsLabel1 = mplsLabel1;
+        this.mplsLabel2 = mplsLabel2;
+    }
+
+    /**
+     * Reads the Evpn type 2 attributes.
+     *
+     * @param cb channel buffer
+     * @return type2 route
+     * @throws BgpParseException parse exception
+     */
+    public static BgpEvpnRouteType2Nlri read(ChannelBuffer cb) throws BgpParseException {
+        if (cb.readableBytes() == 0) {
+            return null;
+        }
+        RouteDistinguisher rd = RouteDistinguisher.read(cb);
+        BgpEvpnEsi esi = BgpEvpnEsi.read(cb);
+        int ethernetTagID = cb.readInt();
+        byte macAddressLength = cb.readByte();
+        MacAddress macAddress = Validation.toMacAddress(macAddressLength / 8, cb);
+        byte ipAddressLength = cb.readByte();
+        InetAddress ipAddress = null;
+        if (ipAddressLength > 0) {
+            ipAddress = Validation.toInetAddress(ipAddressLength / 8, cb);
+        }
+        BgpEvpnLabel mplsLabel1 = BgpEvpnLabel.read(cb);
+        BgpEvpnLabel mplsLabel2 = null;
+        if (cb.readableBytes() > 0) {
+            mplsLabel2 = BgpEvpnLabel.read(cb);
+        }
+
+        return new BgpEvpnRouteType2Nlri(rd, esi, ethernetTagID, macAddress,
+                                         ipAddress, mplsLabel1,
+                                         mplsLabel2);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeLong(rd.getRouteDistinguisher());
+        esi.write(cb);
+        cb.writeInt(ethernetTagID);
+        cb.writeByte(macAddressLength);
+        cb.writeBytes(macAddress.toBytes());
+        cb.writeByte(ipAddressLength);
+        if (ipAddressLength > 0) {
+            cb.writeBytes(ipAddress.getAddress());
+        }
+        mplsLabel1.write(cb);
+        if (mplsLabel2 != null) {
+            mplsLabel2.write(cb);
+        }
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Returns the rd.
+     *
+     * @return rd route distinguisher
+     */
+    public RouteDistinguisher getRouteDistinguisher() {
+        return rd;
+    }
+
+    /**
+     * Returns the esi.
+     *
+     * @return esi ethernet segment identifier
+     */
+    public BgpEvpnEsi getEthernetSegmentidentifier() {
+        return esi;
+    }
+
+    /**
+     * Returns the ethernet tag id.
+     *
+     * @return macAddress macadress
+     */
+    public int getEthernetTagID() {
+        return ethernetTagID;
+    }
+
+    public MacAddress getMacAddress() {
+        return macAddress;
+    }
+
+    /**
+     * Returns the ip address.
+     *
+     * @return ipAddress ipaddress
+     */
+    public InetAddress getIpAddress() {
+        return ipAddress;
+    }
+
+    /**
+     * Returns the mpls label.
+     *
+     * @return mplsLabel1 mpls label
+     */
+    public BgpEvpnLabel getMplsLable1() {
+        return mplsLabel1;
+    }
+
+    /**
+     * Returns the mpls label.
+     *
+     * @return mplsLabel2 mpls label
+     */
+    public BgpEvpnLabel getMplsLable2() {
+        return mplsLabel2;
+    }
+
+    /**
+     * Set the rd.
+     *
+     * @param rd route distinguisher
+     */
+    public void setRouteDistinguisher(RouteDistinguisher rd) {
+        this.rd = rd;
+    }
+
+    /**
+     * Set the ESI.
+     *
+     * @param esi esi
+     */
+    public void setEthernetSegmentidentifier(BgpEvpnEsi esi) {
+        this.esi = esi;
+    }
+
+    /**
+     * Set the ethernet tag id.
+     *
+     * @param ethernetTagID ethernet tag id.
+     */
+    public void setEthernetTagID(int ethernetTagID) {
+        this.ethernetTagID = ethernetTagID;
+    }
+
+    /**
+     * Set the mac address.
+     *
+     * @param macAddress mac
+     */
+    public void setMacAddress(MacAddress macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    /**
+     * Set the ip address.
+     *
+     * @param ipAddress ip
+     */
+    public void setIpAddress(InetAddress ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    /**
+     * Set the mpls label.
+     *
+     * @param mplsLabel1 label
+     */
+    public void setMplsLable1(BgpEvpnLabel mplsLabel1) {
+        this.mplsLabel1 = mplsLabel1;
+    }
+
+    /**
+     * Set the mpls label.
+     *
+     * @param mplsLabel2 label
+     */
+    public void setMplsLable2(BgpEvpnLabel mplsLabel2) {
+        this.mplsLabel2 = mplsLabel2;
+    }
+
+    @Override
+    public BgpEvpnRouteType getType() {
+        return BgpEvpnRouteType.MAC_IP_ADVERTISEMENT;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).omitNullValues()
+                .add("rd ", rd)
+                .add("esi", esi)
+                .add("ethernetTagID", ethernetTagID)
+                .add("macAddressLength", macAddressLength)
+                .add("macAddress ", macAddress)
+                .add("ipAddressLength", ipAddressLength)
+                .add("ipAddress", ipAddress)
+                .add("mplsLabel1 ", mplsLabel1)
+                .add("mplsLabel2", mplsLabel2).toString();
+    }
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java
new file mode 100755
index 0000000..69ee80b
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/evpn/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BGP Protocol evpn components.
+ */
+package org.onosproject.bgpio.protocol.evpn;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
index 9e6b86c..41ece38 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java
@@ -322,6 +322,7 @@
         private boolean isFlowSpecCapabilityTlvSet = false;
         private boolean isVpnFlowSpecCapabilityTlvSet = false;
         private boolean isFlowSpecRpdCapabilityTlvSet = false;
+        private boolean isEvpnCapabilityTlvSet = false;
 
         LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
 
@@ -378,6 +379,12 @@
                 this.capabilityTlv.add(tlv);
             }
 
+            if (this.isEvpnCapabilityTlvSet) {
+                BgpValueType tlv;
+                tlv = new MultiProtocolExtnCapabilityTlv(Constants.AFI_EVPN_VALUE,
+                        RES, Constants.SAFI_EVPN_VALUE);
+                this.capabilityTlv.add(tlv);
+            }
 
             return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId,
                        this.capabilityTlv);
@@ -445,6 +452,12 @@
             this.isFlowSpecRpdCapabilityTlvSet = isFlowSpecRpdCapabilityTlvSet;
             return this;
         }
+
+        @Override
+        public Builder setEvpnCapabilityTlv(boolean isEvpnCapabilitySet) {
+            this.isEvpnCapabilityTlvSet = isEvpnCapabilitySet;
+            return this;
+        }
     }
 
     @Override
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
index 77c3b50..0c12525 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
@@ -246,11 +246,17 @@
                     }
                 }
 
-                if ((afi == Constants.AFI_FLOWSPEC_VALUE) || (afi == Constants.AFI_VALUE)) {
+                if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+                        || (afi == Constants.AFI_VALUE)) {
                     //unfeasible route length
                     cb.writeShort(0);
                 }
 
+                if ((afi == Constants.AFI_EVPN_VALUE)
+                        && (safi == Constants.SAFI_EVPN_VALUE)) {
+                    cb.writeShort(0);
+                }
+
             }
 
             if (message.bgpPathAttributes != null) {
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java
new file mode 100755
index 0000000..b6816e8
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnEsi.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of EthernetSegmentidentifier.
+ */
+public class BgpEvpnEsi
+        implements Comparable<BgpEvpnEsi> {
+
+    public static final int ESI_LENGTH = 10;
+    private byte[] ethernetSegmentidentifier;
+
+    /**
+     * Resets fields.
+     */
+    public BgpEvpnEsi() {
+        this.ethernetSegmentidentifier = null;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param ethernetSegmentidentifier Ethernet Segment identifier
+     */
+    public BgpEvpnEsi(byte[] ethernetSegmentidentifier) {
+        this.ethernetSegmentidentifier = ethernetSegmentidentifier;
+    }
+
+    /**
+     * Reads Ethernet Segment identifier from channelBuffer.
+     *
+     * @param cb channelBuffer
+     * @return object of EthernetSegmentidentifier
+     */
+    public static BgpEvpnEsi read(ChannelBuffer cb) {
+        return new BgpEvpnEsi(cb.readBytes(10).array());
+    }
+
+    /**
+     * writes Ethernet Segment identifier into channelBuffer.
+     *
+     * @param cb channelBuffer
+     * @return length length of written data
+     */
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeBytes(ethernetSegmentidentifier);
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Returns Ethernet Segment identifier.
+     *
+     * @return Ethernet Segment identifier.
+     */
+    public byte[] getEthernetSegmentidentifier() {
+        return this.ethernetSegmentidentifier;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ethernetSegmentidentifier);
+    };
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BgpEvpnEsi) {
+            BgpEvpnEsi that = (BgpEvpnEsi) obj;
+            if (this.ethernetSegmentidentifier == that.ethernetSegmentidentifier) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("ethernetSegmentidentifier", ethernetSegmentidentifier)
+                .toString();
+    }
+
+    @Override
+    public int compareTo(BgpEvpnEsi rd) {
+        return 0;
+    }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java
new file mode 100755
index 0000000..60348ac
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnLabel.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import com.google.common.base.MoreObjects;
+
+public class BgpEvpnLabel implements Comparable<BgpEvpnLabel> {
+
+    public static final int MPLS_LABEL_LENGTH = 3;
+    private byte[] mplsLabel;
+
+    /**
+     * Resets fields.
+     */
+    public BgpEvpnLabel() {
+        this.mplsLabel = null;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param bgpEvpnLabel mpls label
+     */
+    public BgpEvpnLabel(byte[] bgpEvpnLabel) {
+        this.mplsLabel = bgpEvpnLabel;
+    }
+
+    /**
+     * Reads mpls label from channelBuffer.
+     *
+     * @param cb channelBuffer
+     * @return object of mpls label
+     */
+    public static BgpEvpnLabel read(ChannelBuffer cb) {
+        return new BgpEvpnLabel(cb.readBytes(3).array());
+    }
+
+    /**
+     * writes mpls label into channelBuffer.
+     *
+     * @param cb channelBuffer
+     * @return length length of written data
+     */
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeBytes(mplsLabel);
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Returns mpls label.
+     *
+     * @return mpls label
+     */
+    public byte[] getMplsLabel() {
+        return this.mplsLabel;
+    }
+
+    @Override
+    public int compareTo(BgpEvpnLabel mplsLabel) {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BgpEvpnLabel) {
+
+            BgpEvpnLabel that = (BgpEvpnLabel) obj;
+
+            if (this.mplsLabel == that.mplsLabel) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mplsLabel);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("mplsLabel", mplsLabel).toString();
+    }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java
new file mode 100755
index 0000000..142b12e
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpEvpnPrefix.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.types;
+
+import org.onlab.packet.Ip4Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Represents the Evpn prefix.
+ */
+public class BgpEvpnPrefix {
+    private Ip4Address nextHop;
+    private RouteTarget rt;
+    BgpEvpnLabel label;
+
+    /**
+     * Constructor for initializing the evpn prefix.
+     *
+     * @param nextHop next hop
+     * @param rt      route target
+     * @param label   label
+     */
+    public BgpEvpnPrefix(Ip4Address nextHop, RouteTarget rt, BgpEvpnLabel label) {
+        this.nextHop = nextHop;
+        this.rt = rt;
+        this.label = label;
+    }
+
+    /**
+     * Constructor for initializing the evpn prefix.
+     *
+     * @param nextHop next hop
+     * @param label   label
+     */
+    public BgpEvpnPrefix(Ip4Address nextHop, BgpEvpnLabel label) {
+        this.nextHop = nextHop;
+        this.label = label;
+    }
+
+    /**
+     * Get next hop address.
+     *
+     * @return next hop
+     */
+    public Ip4Address getNextHop() {
+        return nextHop;
+    }
+
+    /**
+     * Get the route target.
+     *
+     * @return route target
+     */
+    public RouteTarget getRouteTarget() {
+        return rt;
+    }
+
+    /**
+     * Get the label.
+     *
+     * @return label
+     */
+    public BgpEvpnLabel getLabel() {
+        return label;
+
+    }
+
+    /**
+     * Set the next hop address.
+     *
+     * @param nextHop next hop
+     */
+    public void setNetHop(Ip4Address nextHop) {
+        this.nextHop = nextHop;
+    }
+
+    /**
+     * Set the route target.
+     *
+     * @param rt route target
+     */
+    public void setRouteTarget(RouteTarget rt) {
+        this.rt = rt;
+    }
+
+    /**
+     * Set the label.
+     *
+     * @param label label.
+     */
+    public void setLabel(BgpEvpnLabel label) {
+        this.label = label;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nextHop,
+                            rt,
+                            label);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (!(other instanceof BgpEvpnPrefix)) {
+            return false;
+        }
+
+        BgpEvpnPrefix that = (BgpEvpnPrefix) other;
+
+        return Objects.equals(nextHop, that.nextHop)
+                && Objects.equals(rt, that.rt)
+                && Objects.equals(label, that.label);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("next hop", nextHop)
+                .add("route target", rt)
+                .add("label", label)
+                .toString();
+    }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
index 7462bc8..941ed26 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
@@ -90,6 +90,11 @@
             while (actionBuf.readableBytes() > 0) {
                 short actionType = actionBuf.readShort();
                 switch (actionType) {
+                    case Constants.BGP_ROUTE_TARGET_AS:
+                    case Constants.BGP_ROUTE_TARGET_IP:
+                    case Constants.BGP_ROUTE_TARGET_LARGEAS:
+                        fsActionTlv = RouteTarget.read(actionType, actionBuf);
+                        break;
                     case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION:
                         fsActionTlv = BgpFsActionTrafficAction.read(actionBuf);
                         break;
@@ -102,7 +107,8 @@
                     case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT:
                         fsActionTlv = BgpFsActionReDirect.read(actionBuf);
                         break;
-                    default: log.debug("Other type Not Supported:" + actionType);
+                    default:
+                        log.debug("Other type Not Supported:" + actionType);
                         break;
                 }
                 if (fsActionTlv != null) {
@@ -156,7 +162,13 @@
 
         while (listIterator.hasNext()) {
             BgpValueType fsTlv = listIterator.next();
-            if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
+            if (fsTlv.getType() == Constants.BGP_ROUTE_TARGET_AS
+                    || fsTlv.getType() == Constants.BGP_ROUTE_TARGET_IP
+                    || fsTlv.getType() == Constants.BGP_ROUTE_TARGET_LARGEAS) {
+                RouteTarget routeTarget = (RouteTarget) fsTlv;
+                routeTarget.write(cb);
+            } else if (fsTlv.getType() == Constants
+                    .BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
                 BgpFsActionTrafficAction trafficAction = (BgpFsActionTrafficAction) fsTlv;
                 trafficAction.write(cb);
             } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING) {
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java
new file mode 100755
index 0000000..29b318d
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpNlriType.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.types;
+
+public enum BgpNlriType {
+
+    /**
+     * Signifies Link State Nlri.
+     */
+    LINK_STATE,
+    /**
+     * Signifies Flow Spec Nlri.
+     */
+    FLOW_SPEC,
+    /**
+     * Signifies Evpn Nlri.
+     */
+    EVPN;
+
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
index 328b623..106c4bb 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java
@@ -16,25 +16,27 @@
 
 package org.onosproject.bgpio.types;
 
-import java.net.InetAddress;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
+import com.google.common.base.MoreObjects;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.onlab.packet.Ip4Address;
 import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
 import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
 import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
-import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
 import org.onosproject.bgpio.util.Constants;
 import org.onosproject.bgpio.util.Validation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.MoreObjects;
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
 
 /*
  * Provides Implementation of MpReach Nlri BGP Path Attribute.
@@ -52,6 +54,7 @@
     private final byte safi;
     private final Ip4Address ipNextHop;
     private BgpFlowSpecNlri bgpFlowSpecNlri;
+    private List<BgpEvpnNlri> evpnNlri;
 
     /**
      * Constructor to initialize parameters.
@@ -71,6 +74,13 @@
         this.length = length;
     }
 
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param bgpFlowSpecNlri bgpFlowSpecNlri
+     * @param afi             afi
+     * @param safi            safi
+     */
     public MpReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
         this.mpReachNlri = null;
         this.isMpReachNlri = true;
@@ -82,6 +92,24 @@
     }
 
     /**
+     * Constructor to initialize parameters.
+     *
+     * @param evpnNlri  evpnNlri
+     * @param afi       afi
+     * @param safi      safi
+     * @param ipNextHop IP Nexthop
+     */
+    public MpReachNlri(List<BgpEvpnNlri> evpnNlri, short afi, byte safi, Ip4Address ipNextHop) {
+        this.mpReachNlri = null;
+        this.length = 42;
+        this.ipNextHop = ipNextHop;
+        this.isMpReachNlri = true;
+        this.evpnNlri = evpnNlri;
+        this.afi = afi;
+        this.safi = safi;
+    }
+
+    /**
      * Returns whether MpReachNlri is present.
      *
      * @return whether MpReachNlri is present
@@ -118,6 +146,60 @@
     }
 
     /**
+     * Returns BGP Evpn info.
+     *
+     * @return BGP Evpn info
+     */
+    public List<BgpEvpnNlri> bgpEvpnNlri() {
+        return this.evpnNlri;
+    }
+
+    /**
+     * Returns afi.
+     *
+     * @return afi
+     */
+    public short getAfi() {
+        return this.afi;
+    }
+
+    /**
+     * Returns safi.
+     *
+     * @return safi
+     */
+    public byte getSafi() {
+        return this.safi();
+    }
+
+    /**
+     * Returns mpReachNlri details type.
+     *
+     * @return type
+     */
+    public BgpNlriType getNlriDetailsType() {
+        if ((this.afi == Constants.AFI_VALUE)
+                && (this.safi == Constants.SAFI_VALUE)
+                || (this.afi == Constants.AFI_VALUE)
+                && (this.safi == Constants.VPN_SAFI_VALUE)) {
+            return BgpNlriType.LINK_STATE;
+        }
+
+        if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+                && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
+                || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
+            return BgpNlriType.FLOW_SPEC;
+        }
+
+        if ((afi == Constants.AFI_EVPN_VALUE)
+                && (safi == Constants.SAFI_EVPN_VALUE)) {
+            return BgpNlriType.EVPN;
+        }
+
+        return null;
+    }
+
+    /**
      * Reads from ChannelBuffer and parses MpReachNlri.
      *
      * @param cb channelBuffer
@@ -272,6 +354,29 @@
                 BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
                 flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
                 return new MpReachNlri(flowSpecDetails, afi, safi);
+            } else if ((afi == Constants.AFI_EVPN_VALUE)
+                    && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+                List<BgpEvpnNlri> eVpnComponents = null;
+
+                byte nextHopLen = tempCb.readByte();
+                InetAddress ipAddress = Validation.toInetAddress(nextHopLen,
+                                                                 tempCb);
+                if (ipAddress.isMulticastAddress()) {
+                    throw new BgpParseException("Multicast not supported");
+                }
+                ipNextHop = Ip4Address.valueOf(ipAddress);
+                byte reserved = tempCb.readByte();
+                while (tempCb.readableBytes() > 0) {
+                    BgpEvpnNlri eVpnComponent = BgpEvpnNlriImpl.read(tempCb);
+                    eVpnComponents = new LinkedList<>();
+                    eVpnComponents.add(eVpnComponent);
+                    log.info("=====evpn Component is {} ======", eVpnComponent);
+                }
+
+                return new MpReachNlri(eVpnComponents, afi, safi, ipNextHop);
+
+
             } else {
                 throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
             }
@@ -358,6 +463,48 @@
             int fsNlriLen = cb.writerIndex() - mpReachDataIndx;
             cb.setShort(mpReachDataIndx, (short) (fsNlriLen - 2));
 
+        } else if ((afi == Constants.AFI_EVPN_VALUE)
+                && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+            cb.writeByte(FLAGS);
+            cb.writeByte(MPREACHNLRI_TYPE);
+
+            int mpReachDataIndex = cb.writerIndex();
+            cb.writeShort(0);
+            cb.writeShort(afi);
+            cb.writeByte(safi);
+            // ip address length
+            cb.writeByte(0x04);
+            cb.writeInt(ipNextHop.toInt());
+            //sub network points of attachment
+            cb.writeByte(0);
+
+            for (BgpEvpnNlri element : evpnNlri) {
+                short routeType = element.getType();
+                switch (routeType) {
+                    case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+                        cb.writeByte(element.getType());
+                        int iSpecStartIndex = cb.writerIndex();
+                        cb.writeByte(0);
+                        BgpEvpnRouteType2Nlri macIpAdvNlri = (BgpEvpnRouteType2Nlri) element
+                                .getNlri();
+                        macIpAdvNlri.write(cb);
+                        cb.setByte(iSpecStartIndex, (byte) (cb.writerIndex()
+                                - iSpecStartIndex - 1));
+                        //ChannelBuffer temcb = cb.copy();
+                        break;
+                    case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+                        break;
+                    case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+                        break;
+                    case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+                        break;
+                    default:
+                        break;
+                }
+            }
+            int evpnNlriLen = cb.writerIndex() - mpReachDataIndex;
+            cb.setShort(mpReachDataIndex, (short) (evpnNlriLen - 2));
         }
 
         return cb.writerIndex() - iLenStartIndex;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
index 9bc0189..e06fb0a 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java
@@ -16,23 +16,25 @@
 
 package org.onosproject.bgpio.types;
 
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
+import com.google.common.base.MoreObjects;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpEvpnNlri;
 import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
+import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
 import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
 import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
 import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
-import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
 import org.onosproject.bgpio.util.Constants;
 import org.onosproject.bgpio.util.Validation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.MoreObjects;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
 
 /**
  * Provides Implementation of MpUnReach Nlri BGP Path Attribute.
@@ -49,6 +51,7 @@
     private final List<BgpLSNlri> mpUnReachNlri;
     private final int length;
     private BgpFlowSpecNlri bgpFlowSpecNlri;
+    private List<BgpEvpnNlri> evpnNlri;
 
     /**
      * Constructor to initialize parameters.
@@ -67,6 +70,13 @@
         this.length = length;
     }
 
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param bgpFlowSpecNlri bgpFlowSpecNlri
+     * @param afi             afi
+     * @param safi            safi
+     */
     public MpUnReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
         this.mpUnReachNlri = null;
         this.isMpUnReachNlri = true;
@@ -77,6 +87,22 @@
     }
 
     /**
+     * Constructor to initialize parameters.
+     *
+     * @param evpnNlri evpnNlri
+     * @param afi      afi
+     * @param safi     safi
+     */
+    public MpUnReachNlri(List<BgpEvpnNlri> evpnNlri, short afi, byte safi) {
+        this.mpUnReachNlri = null;
+        this.isMpUnReachNlri = true;
+        this.length = 0;
+        this.evpnNlri = evpnNlri;
+        this.afi = afi;
+        this.safi = safi;
+    }
+
+    /**
      * Returns BGP flow specification info.
      *
      * @return BGP flow specification info
@@ -86,6 +112,60 @@
     }
 
     /**
+     * Returns BGP Evpn info.
+     *
+     * @return BGP Evpn info
+     */
+    public List<BgpEvpnNlri> bgpEvpnNlri() {
+        return this.evpnNlri;
+    }
+
+    /**
+     * Returns afi.
+     *
+     * @return afi
+     */
+    public short getAfi() {
+        return this.afi;
+    }
+
+    /**
+     * Returns safi.
+     *
+     * @return safi
+     */
+    public byte getSafi() {
+        return this.safi();
+    }
+
+    /**
+     * Returns mpUnReachNlri details type.
+     *
+     * @return type
+     */
+    public BgpNlriType getNlriDetailsType() {
+        if ((this.afi == Constants.AFI_VALUE)
+                && (this.safi == Constants.SAFI_VALUE)
+                || (this.afi == Constants.AFI_VALUE)
+                && (this.safi == Constants.VPN_SAFI_VALUE)) {
+            return BgpNlriType.LINK_STATE;
+        }
+
+        if ((afi == Constants.AFI_FLOWSPEC_VALUE)
+                && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
+                || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
+            return BgpNlriType.FLOW_SPEC;
+        }
+
+        if ((afi == Constants.AFI_EVPN_VALUE)
+                && (safi == Constants.SAFI_EVPN_VALUE)) {
+            return BgpNlriType.EVPN;
+        }
+
+        return null;
+    }
+
+    /**
      * Reads from ChannelBuffer and parses MpUnReachNlri.
      *
      * @param cb ChannelBuffer
@@ -226,6 +306,17 @@
                 BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
                 flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
                 return new MpUnReachNlri(flowSpecDetails, afi, safi);
+            } else if ((afi == Constants.AFI_EVPN_VALUE)
+                    && (safi == Constants.SAFI_EVPN_VALUE)) {
+                List<BgpEvpnNlri> eVpnComponents = null;
+                while (tempCb.readableBytes() > 0) {
+                    BgpEvpnNlri eVpnComponent = BgpEvpnNlriImpl.read(tempCb);
+                    eVpnComponents = new LinkedList<>();
+                    eVpnComponents.add(eVpnComponent);
+                    log.info("=====evpn Component is {} ======", eVpnComponent);
+                }
+
+                return new MpUnReachNlri(eVpnComponents, afi, safi);
             } else {
                 //TODO: check with the values got from capability
                 throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
@@ -326,6 +417,45 @@
             }
             int fsNlriLen = cb.writerIndex() - mpUnReachIndx;
             cb.setShort(mpUnReachIndx, (short) (fsNlriLen - 2));
+        } else if ((afi == Constants.AFI_EVPN_VALUE)
+                && (safi == Constants.SAFI_EVPN_VALUE)) {
+
+            cb.writeByte(FLAGS);
+            cb.writeByte(MPUNREACHNLRI_TYPE);
+
+            int mpUnReachDataIndex = cb.writerIndex();
+            cb.writeShort(0);
+            cb.writeShort(afi);
+            cb.writeByte(safi);
+
+            for (BgpEvpnNlri element : evpnNlri) {
+                short routeType = element.getType();
+                switch (routeType) {
+                    case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
+                        cb.writeByte(element.getType());
+                        int iSpecStartIndex = cb.writerIndex();
+                        cb.writeByte(0);
+                        BgpEvpnRouteType2Nlri macIpAdvNlri =
+                                (BgpEvpnRouteType2Nlri) element
+                                        .getNlri();
+
+                        macIpAdvNlri.write(cb);
+                        cb.setByte(iSpecStartIndex, (short) (cb.writerIndex()
+                                - iSpecStartIndex - 1));
+                        break;
+                    case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
+                        break;
+                    case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
+                        break;
+                    case Constants.BGP_EVPN_ETHERNET_SEGMENT:
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            int evpnNlriLen = cb.writerIndex() - mpUnReachDataIndex;
+            cb.setShort(mpUnReachDataIndex, (short) (evpnNlriLen - 2));
         }
 
         return cb.writerIndex() - iLenStartIndex;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java
new file mode 100755
index 0000000..5a009f9
--- /dev/null
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteTarget.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgpio.types;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+
+/**
+ * Implementation of RouteTarget.
+ */
+public class RouteTarget implements BgpValueType {
+
+    /*
+     * Type 0x00: Local Administrator sub-field uses 2 octets with AS number and
+     * Assigned number uses 4 octests Type 0x01: Local Administrator sub-field
+     * uses 4 octets with IP address and Assigned number uses 2 octests Type
+     * 0x02: Local Administrator sub-field uses 4 octets with AS number and
+     * Assigned number uses 2 octests
+     */
+    private byte[] routeTarget;
+    private short type;
+
+    public enum RouteTargetype {
+
+        AS((short) 0x0002), IP((short) 0x0102), LARGEAS((short) 0x0202);
+        short value;
+
+        /**
+         * Assign val with the value as the tunnel type.
+         *
+         * @param val tunnel type
+         */
+        RouteTargetype(short val) {
+            value = val;
+        }
+
+        /**
+         * Returns value of route type.
+         *
+         * @return route type
+         */
+        public short getType() {
+            return value;
+        }
+    }
+
+    /**
+     * Resets fields.
+     */
+    public RouteTarget() {
+        this.type = 0;
+        this.routeTarget = null;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param type        type
+     * @param routeTarget route target
+     */
+    public RouteTarget(short type, byte[] routeTarget) {
+        this.type = type;
+        this.routeTarget = routeTarget;
+    }
+
+    /**
+     * Reads route target from channelBuffer.
+     *
+     * @param type type
+     * @param cb   channelBuffer
+     * @return object of RouteTarget
+     */
+    public static RouteTarget read(short type, ChannelBuffer cb) {
+        return new RouteTarget(type, cb.readBytes(6).array());
+    }
+
+    /**
+     * Returns route target.
+     *
+     * @return route target
+     */
+    public byte[] getRouteTarget() {
+        return this.routeTarget;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof RouteTarget) {
+            RouteTarget that = (RouteTarget) obj;
+            if (this.type == that.type
+                    && this.routeTarget == that.routeTarget) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(routeTarget);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("type", type)
+                .add("routeTarget", routeTarget).toString();
+    }
+
+    @Override
+    public short getType() {
+        return type;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeShort(type);
+        cb.writeBytes(routeTarget);
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    @Override
+    public int compareTo(Object rd) {
+        return 0;
+    }
+}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
index 43d31c5..1839a31 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Constants.java
@@ -46,6 +46,9 @@
     public static final byte SAFI_FLOWSPEC_RPD_VALUE = (byte) 133;
     public static final byte VPN_SAFI_FLOWSPEC_RDP_VALUE = (byte) 134;
 
+    public static final short AFI_EVPN_VALUE = 25;
+    public static final byte SAFI_EVPN_VALUE = (byte) 70;
+
     public static final byte RPD_CAPABILITY_RECEIVE_VALUE = 0;
     public static final byte RPD_CAPABILITY_SEND_VALUE = 1;
     public static final byte RPD_CAPABILITY_SEND_RECEIVE_VALUE = 2;
@@ -73,6 +76,15 @@
     public static final byte BGP_FLOWSPEC_DSCP = 0x0b;
     public static final byte BGP_FLOWSPEC_FRAGMENT = 0x0c;
 
+    // for EVPN
+    public static final short BGP_ROUTE_TARGET_AS = (short) 0x0002;
+    public static final short BGP_ROUTE_TARGET_IP = (short) 0x0102;
+    public static final short BGP_ROUTE_TARGET_LARGEAS = (short) 0x0202;
+    public static final short BGP_EVPN_ETHERNET_AUTO_DISCOVERY = (short) 0x01;
+    public static final short BGP_EVPN_MAC_IP_ADVERTISEMENT = (short) 0x02;
+    public static final short BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET = (short) 0x03;
+    public static final short BGP_EVPN_ETHERNET_SEGMENT = (short) 0x04;
+
     public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_RATE = (short) 0x8006;
     public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION = (short) 0x8007;
     public static final short BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT = (short) 0x8008;
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
index 93eb376..3f06487 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
@@ -24,6 +24,7 @@
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
 import org.onosproject.bgpio.exceptions.BgpParseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -151,7 +152,19 @@
         }
         return ipAddress;
     }
-
+    /**
+     * Convert byte array to MacAddress.
+     *
+     * @param length of MacAddress
+     * @param cb channelBuffer
+     * @return macAddress
+     */
+    public static MacAddress toMacAddress(int length, ChannelBuffer cb) {
+        byte[] address = new byte[length];
+        cb.readBytes(address, 0, length);
+        MacAddress macAddress = MacAddress.valueOf(address);
+        return macAddress;
+    }
     /**
      * Returns first bit in type flags.
      *