Adding EVPN App code

Change-Id: Id3b2192f56f054cadcd8384092245b8757a781a9
diff --git a/apps/evpnopenflow/BUCK b/apps/evpnopenflow/BUCK
new file mode 100755
index 0000000..6554cc7
--- /dev/null
+++ b/apps/evpnopenflow/BUCK
@@ -0,0 +1,27 @@
+COMPILE_DEPS = [
+  '//lib:CORE_DEPS',
+  '//lib:org.apache.karaf.shell.console',
+  '//cli:onos-cli',
+  '//incubator/api:onos-incubator-api',
+  '//core/store/serializers:onos-core-serializers',
+  '//apps/gluon:onos-apps-gluon',
+  '//apps/vtn/vtnrsc:onos-apps-vtn-vtnrsc',
+]
+
+TEST_DEPS = [
+  '//lib:TEST_ADAPTERS',
+  '//lib:TEST',
+]
+
+osgi_jar_with_tests(
+  deps = COMPILE_DEPS,
+  test_deps = TEST_DEPS,
+)
+
+onos_app(
+  title = 'Evpn-openflow App',
+  category = 'Traffic Steering',
+  url = 'http://onosproject.org',
+  description = 'Ethernet VPN (EVPN) introduces a new model for Ethernet services delivery.' +
+  'It enables integrated Layer 2 service over Ethernet with multihoming.',
+)
diff --git a/apps/evpnopenflow/pom.xml b/apps/evpnopenflow/pom.xml
new file mode 100755
index 0000000..aa4aab7
--- /dev/null
+++ b/apps/evpnopenflow/pom.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright 2017-present 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.
+  -->
+<project
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+        xmlns="http://maven.apache.org/POM/4.0.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.11.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>onos-app-evpnopenflow</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONOS EVPN application</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.evpnopenflow</onos.app.name>
+        <onos.app.title>ONOS EVPN openflow App</onos.app.title>
+        <onos.app.category>Traffic steering</onos.app.category>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+        <onos.app.readme>ONOS EVPN openflow application.</onos.app.readme>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-gluon</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-vtn-rsc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java
new file mode 100755
index 0000000..560b96e
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/EvpnService.java
@@ -0,0 +1,76 @@
+/*
+ * 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.evpnopenflow.manager;
+
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.net.Host;
+
+/**
+ * Service for interacting with the route and host events.
+ */
+public interface EvpnService {
+    /**
+     * Transfer remote route to private route and set mpls flows out when
+     * BgpRoute update.
+     *
+     * @param route evpn route
+     */
+    void onBgpEvpnRouteUpdate(EvpnRoute route);
+
+    /**
+     * Transfer remote route to private route and delete mpls flows out when
+     * BgpRoute delete.
+     *
+     * @param route evpn route
+     */
+    void onBgpEvpnRouteDelete(EvpnRoute route);
+
+    /**
+     * Get VPN info from EVPN app store and create route, set flows when host
+     * detected.
+     *
+     * @param host host information
+     */
+    void onHostDetected(Host host);
+
+    /**
+     * Get VPN info from EVPN app store and delete route, set flows when
+     * host
+     * vanished.
+     *
+     * @param host host information
+     */
+    void onHostVanished(Host host);
+
+    /**
+     * Get VPN info from EVPN app store and create route, set flows when
+     * host
+     * detected.
+     *
+     * @param vpnPort vpnPort information
+     */
+    void onVpnPortSet(VpnPort vpnPort);
+
+    /**
+     * Get VPN info from EVPN app store and delete route, set flows when host
+     * vanished.
+     *
+     * @param vpnPort vpnPort information
+     */
+    void onVpnPortDelete(VpnPort vpnPort);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java
new file mode 100755
index 0000000..7f7314b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/EvpnManager.java
@@ -0,0 +1,1132 @@
+/*
+ * 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.evpnopenflow.manager.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MplsLabel;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.manager.EvpnService;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+import org.onosproject.evpnopenflow.rsc.VpnInstance;
+import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnPortId;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
+import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
+import org.onosproject.gluon.rsc.GluonConfig;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.routing.EvpnInstanceName;
+import org.onosproject.incubator.net.routing.EvpnInstanceNextHop;
+import org.onosproject.incubator.net.routing.EvpnInstancePrefix;
+import org.onosproject.incubator.net.routing.EvpnInstanceRoute;
+import org.onosproject.incubator.net.routing.EvpnNextHop;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.incubator.net.routing.EvpnRoute.Source;
+import org.onosproject.incubator.net.routing.EvpnRouteAdminService;
+import org.onosproject.incubator.net.routing.EvpnRouteEvent;
+import org.onosproject.incubator.net.routing.EvpnRouteListener;
+import org.onosproject.incubator.net.routing.EvpnRouteService;
+import org.onosproject.incubator.net.routing.EvpnRouteSet;
+import org.onosproject.incubator.net.routing.EvpnRouteStore;
+import org.onosproject.incubator.net.routing.Label;
+import org.onosproject.incubator.net.routing.RouteDistinguisher;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.Objective.Operation;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type.Reference;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_PRIORITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ARP_RESPONSE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASEPORT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_DELETE_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BGP_EVPN_ROUTE_UPDATE_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BOTH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANNOT_FIND_TUNNEL_PORT_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_CONTROLLER_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_INSTANCE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CANT_FIND_VPN_PORT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_OPENFLOW_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_EXTCOMMUNITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FAILED_TO_SET_TUNNEL_DST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.GET_PRIVATE_LABEL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_DETECT;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.HOST_VANISHED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IFACEID_OF_HOST_IS_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_EXTCOMMUNITY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_EVENT_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ROUTE_TARGET_TYPE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_TARGET_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.MPLS_OUT_FLOWS;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NETWORK_CONFIG_EVENT_IS_RECEIVED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.NOT_MASTER_FOR_SPECIFIC_DEVICE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RELEASE_LABEL_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_ADD_ARP_RULES;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_REMOVE_ARP_RULES;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SWITCH_CHANNEL_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.TUNNEL_DST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_BIND;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_TARGET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UNBIND;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VXLAN;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the EVPN service.
+ */
+@Component(immediate = true)
+@Service
+public class EvpnManager implements EvpnService {
+    private final Logger log = getLogger(getClass());
+    private static final EthType.EtherType ARP_TYPE = EthType.EtherType.ARP;
+
+    protected ApplicationId appId;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteService evpnRouteService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteStore evpnRouteStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EvpnRouteAdminService evpnRouteAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceAdminService labelAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceService labelService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnInstanceService vpnInstanceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnPortService vpnPortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnAfConfigService vpnAfConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    public Set<EvpnInstanceRoute> evpnInstanceRoutes = new HashSet<>();
+    private final HostListener hostListener = new InnerHostListener();
+    private final VpnPortListener vpnPortListner = new InnerVpnPortListener();
+    private final VpnAfConfigListener vpnAfConfigListener = new
+            InnerVpnAfConfigListener();
+    private final InternalRouteEventListener routeListener = new
+            InternalRouteEventListener();
+
+    private final NetworkConfigListener configListener = new
+            InternalNetworkConfigListener();
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        hostService.addListener(hostListener);
+        vpnPortService.addListener(vpnPortListner);
+        vpnAfConfigService.addListener(vpnAfConfigListener);
+        configService.addListener(configListener);
+        evpnRouteService.addListener(routeListener);
+
+        labelAdminService
+                .createGlobalPool(LabelResourceId.labelResourceId(1),
+                                  LabelResourceId.labelResourceId(1000));
+        log.info(EVPN_OPENFLOW_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        hostService.removeListener(hostListener);
+        vpnPortService.removeListener(vpnPortListner);
+        vpnAfConfigService.removeListener(vpnAfConfigListener);
+        configService.removeListener(configListener);
+        log.info(EVPN_OPENFLOW_STOP);
+    }
+
+    @Override
+    public void onBgpEvpnRouteUpdate(EvpnRoute route) {
+        if (EvpnRoute.Source.LOCAL.equals(route.source())) {
+            return;
+        }
+        log.info(BGP_EVPN_ROUTE_UPDATE_START, route);
+        // deal with public route and transfer to private route
+        if (vpnInstanceService.getInstances().isEmpty()) {
+            log.info("unable to get instnaces from vpninstance");
+            return;
+        }
+
+        vpnInstanceService.getInstances().forEach(vpnInstance -> {
+            log.info("got instnaces from vpninstance but not entered here");
+            List<VpnRouteTarget> vpnImportRouteRt = new
+                    LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> expRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(expRt);
+            similar.retainAll(vpnImportRouteRt);
+
+            if (!similar.isEmpty()) {
+                EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                        .evpnPrefix(route.prefixMac(), route.prefixIp());
+
+                EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                        .evpnNextHop(route.ipNextHop(), route.label());
+
+                EvpnInstanceRoute evpnPrivateRoute = new
+                        EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
+                                          route.routeDistinguisher(),
+                                          vpnImportRouteRt,
+                                          route.exportRouteTarget(),
+                                          evpnPrefix,
+                                          evpnNextHop,
+                                          route.prefixIp(),
+                                          route.ipNextHop(),
+                                          route.label());
+
+                //update route in route subsystem
+                //TODO: added by shahid
+                evpnInstanceRoutes.add(evpnPrivateRoute);
+
+            }
+        });
+
+        deviceService.getAvailableDevices(Device.Type.SWITCH)
+                .forEach(device -> {
+                    log.info("switch device is found");
+                    Set<Host> hosts = getHostsByVpn(device, route);
+                    for (Host h : hosts) {
+                        addArpFlows(device.id(),
+                                    route,
+                                    Objective.Operation.ADD,
+                                    h);
+                        ForwardingObjective.Builder objective =
+                                getMplsOutBuilder(device.id(),
+                                                  route,
+                                                  h);
+                        log.info(MPLS_OUT_FLOWS, h);
+                        flowObjectiveService.forward(device.id(),
+                                                     objective.add());
+                    }
+                });
+        log.info("no switch device is found");
+    }
+
+    @Override
+    public void onBgpEvpnRouteDelete(EvpnRoute route) {
+        if (EvpnRoute.Source.LOCAL.equals(route.source())) {
+            return;
+        }
+        log.info(BGP_EVPN_ROUTE_DELETE_START, route);
+        // deal with public route deleted and transfer to private route
+        vpnInstanceService.getInstances().forEach(vpnInstance -> {
+            List<VpnRouteTarget> vpnRouteRt = new
+                    LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> localRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(localRt);
+            similar.retainAll(vpnRouteRt);
+
+            if (!similar.isEmpty()) {
+                EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                        .evpnPrefix(route.prefixMac(), route.prefixIp());
+
+                EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                        .evpnNextHop(route.ipNextHop(), route.label());
+
+                EvpnInstanceRoute evpnPrivateRoute = new
+                        EvpnInstanceRoute(vpnInstance.vpnInstanceName(),
+                                          route.routeDistinguisher(),
+                                          vpnRouteRt,
+                                          route.exportRouteTarget(),
+                                          evpnPrefix,
+                                          evpnNextHop,
+                                          route.prefixIp(),
+                                          route.ipNextHop(),
+                                          route.label());
+                //TODO: Added by Shahid
+                //evpnRouteAdminService.withdraw(Sets.newHashSet
+                //       (evpnPrivateRoute));
+
+            }
+        });
+        deviceService.getAvailableDevices(Device.Type.SWITCH)
+                .forEach(device -> {
+                    Set<Host> hosts = getHostsByVpn(device, route);
+                    for (Host h : hosts) {
+                        addArpFlows(device.id(),
+                                    route,
+                                    Objective.Operation.REMOVE,
+                                    h);
+                        ForwardingObjective.Builder objective
+                                = getMplsOutBuilder(device.id(),
+                                                    route,
+                                                    h);
+                        flowObjectiveService.forward(device.id(),
+                                                     objective.remove());
+                    }
+                });
+    }
+
+    private void addArpFlows(DeviceId deviceId,
+                             EvpnRoute route,
+                             Operation type,
+                             Host host) {
+        DriverHandler handler = driverService.createHandler(deviceId);
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(ARP_TYPE.ethType().toShort())
+                .matchArpTpa(route.prefixIp().address().getIp4Address())
+                .matchInPort(host.location().port()).build();
+
+        ExtensionTreatmentResolver resolver = handler
+                .behaviour(ExtensionTreatmentResolver.class);
+        ExtensionTreatment ethSrcToDst = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ETH_SRC_TO_DST
+                                                 .type());
+        ExtensionTreatment arpShaToTha = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ARP_SHA_TO_THA
+                                                 .type());
+        ExtensionTreatment arpSpaToTpa = resolver
+                .getExtensionInstruction(ExtensionTreatmentType
+                                                 .ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_ARP_SPA_TO_TPA
+                                                 .type());
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .extension(ethSrcToDst, deviceId).setEthSrc(route.prefixMac())
+                .setArpOp(ARP_RESPONSE).extension(arpShaToTha, deviceId)
+                .extension(arpSpaToTpa, deviceId).setArpSha(route.prefixMac())
+                .setArpSpa(route.prefixIp().address().getIp4Address())
+                .setOutput(PortNumber.IN_PORT)
+                .build();
+
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(ARP_PRIORITY);
+        if (type.equals(Objective.Operation.ADD)) {
+            log.info(ROUTE_ADD_ARP_RULES);
+            flowObjectiveService.forward(deviceId, objective.add());
+        } else {
+            log.info(ROUTE_REMOVE_ARP_RULES);
+            flowObjectiveService.forward(deviceId, objective.remove());
+        }
+    }
+
+    private Set<Host> getHostsByVpn(Device device, EvpnRoute route) {
+        Set<Host> vpnHosts = Sets.newHashSet();
+        Set<Host> hosts = hostService.getConnectedHosts(device.id());
+        for (Host h : hosts) {
+            String ifaceId = h.annotations().value(IFACEID);
+            if (!vpnPortService.exists(VpnPortId.vpnPortId(ifaceId))) {
+                continue;
+            }
+
+            VpnPort vpnPort = vpnPortService
+                    .getPort(VpnPortId.vpnPortId(ifaceId));
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+
+            List<VpnRouteTarget> expRt = route.exportRouteTarget();
+            List<VpnRouteTarget> similar = new LinkedList<>(expRt);
+            similar.retainAll(vpnInstance.getImportRouteTargets());
+            //TODO: currently checking for RT comparision.
+            //TODO: Need to check about RD comparision is really required.
+            //if (route.routeDistinguisher()
+            //.equals(vpnInstance.routeDistinguisher())) {
+            if (!similar.isEmpty()) {
+                vpnHosts.add(h);
+            }
+        }
+        return vpnHosts;
+    }
+
+    private ForwardingObjective.Builder getMplsOutBuilder(DeviceId deviceId,
+                                                          EvpnRoute route,
+                                                          Host h) {
+        DriverHandler handler = driverService.createHandler(deviceId);
+        ExtensionTreatmentResolver resolver = handler
+                .behaviour(ExtensionTreatmentResolver.class);
+        ExtensionTreatment treatment = resolver
+                .getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+        try {
+            treatment.setPropertyValue(TUNNEL_DST, route.ipNextHop());
+        } catch (Exception e) {
+            log.error(FAILED_TO_SET_TUNNEL_DST, deviceId);
+        }
+        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+        builder.extension(treatment, deviceId);
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(h.location().port()).matchEthSrc(h.mac())
+                .matchEthDst(route.prefixMac()).build();
+
+        TrafficTreatment build = builder.pushMpls()
+                .setMpls(MplsLabel.mplsLabel(route.label().getLabel()))
+                .setOutput(getTunnlePort(deviceId)).build();
+
+        return DefaultForwardingObjective
+                .builder().withTreatment(build).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(60000);
+
+    }
+
+    private ForwardingObjective.Builder getMplsInBuilder(DeviceId deviceId,
+                                                         Host host,
+                                                         Label label) {
+        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(getTunnlePort(deviceId))
+                .matchEthType(EthType.EtherType.MPLS_UNICAST.ethType()
+                                      .toShort())
+                .matchMplsBos(true)
+                .matchMplsLabel(MplsLabel.mplsLabel(label.getLabel())).build();
+        TrafficTreatment treatment = builder.popMpls(EthType
+                                                             .EtherType
+                                                             .IPV4.ethType())
+                .setOutput(host.location().port()).build();
+        return DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .withPriority(60000);
+    }
+
+    /**
+     * Get local tunnel ports.
+     *
+     * @param ports Iterable of Port
+     * @return Collection of PortNumber
+     */
+    private Collection<PortNumber> getLocalTunnelPorts(Iterable<Port>
+                                                               ports) {
+        Collection<PortNumber> localTunnelPorts = new ArrayList<>();
+        if (ports != null) {
+            log.info("port value is not null {}", ports);
+            Sets.newHashSet(ports).stream()
+                    .filter(p -> !p.number().equals(PortNumber.LOCAL))
+                    .forEach(p -> {
+                        log.info("number is not matched but no vxlan port");
+                        if (p.annotations().value(AnnotationKeys.PORT_NAME)
+                                .startsWith(VXLAN)) {
+                            localTunnelPorts.add(p.number());
+                        }
+                    });
+        }
+        return localTunnelPorts;
+    }
+
+    private PortNumber getTunnlePort(DeviceId deviceId) {
+        Iterable<Port> ports = deviceService.getPorts(deviceId);
+        Collection<PortNumber> localTunnelPorts = getLocalTunnelPorts(ports);
+        if (localTunnelPorts.isEmpty()) {
+            log.error(CANNOT_FIND_TUNNEL_PORT_DEVICE, deviceId);
+            return null;
+        }
+        return localTunnelPorts.iterator().next();
+    }
+
+    private void setFlows(DeviceId deviceId, Host host, Label label,
+                          List<VpnRouteTarget> rtImport,
+                          Operation type) {
+        log.info("Set the flows to OVS");
+        ForwardingObjective.Builder objective = getMplsInBuilder(deviceId,
+                                                                 host,
+                                                                 label);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(deviceId, objective.add());
+        } else {
+            flowObjectiveService.forward(deviceId, objective.remove());
+        }
+
+        // download remote flows if and only routes are present.
+        evpnRouteStore.getRouteTables().forEach(routeTableId -> {
+            Collection<EvpnRouteSet> routes
+                    = evpnRouteStore.getRoutes(routeTableId);
+            if (routes != null) {
+                routes.forEach(route -> {
+                    Collection<EvpnRoute> evpnRoutes = route.routes();
+                    for (EvpnRoute evpnRoute : evpnRoutes) {
+                        EvpnRoute evpnRouteTem = evpnRoute;
+                        Set<Host> hostByMac = hostService
+                                .getHostsByMac(evpnRouteTem
+                                                       .prefixMac());
+
+                        if (!hostByMac.isEmpty()
+                                || (!(compareLists(rtImport, evpnRouteTem
+                                .exportRouteTarget())))) {
+                            log.info("Route target import/export is not matched");
+                            continue;
+                        }
+                        log.info("Set the ARP flows");
+                        addArpFlows(deviceId, evpnRouteTem, type, host);
+                        ForwardingObjective.Builder build = getMplsOutBuilder(deviceId,
+                                                                              evpnRouteTem,
+                                                                              host);
+                        log.info("Set the MPLS  flows");
+                        if (type.equals(Objective.Operation.ADD)) {
+                            flowObjectiveService.forward(deviceId, build.add());
+                        } else {
+                            flowObjectiveService.forward(deviceId, build.remove());
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    /**
+     * comparison for tow lists.
+     *
+     * @param list1 import list
+     * @param list2 export list
+     * @return true or false
+     */
+    public static boolean compareLists(List<VpnRouteTarget> list1,
+                                       List<VpnRouteTarget> list2) {
+        if (list1 == null && list2 == null) {
+            return true;
+        }
+
+        if (list1 != null && list2 != null) {
+            if (list1.size() == list2.size()) {
+                for (VpnRouteTarget li1Long : list1) {
+                    boolean isEqual = false;
+                    for (VpnRouteTarget li2Long : list2) {
+                        if (li1Long.equals(li2Long)) {
+                            isEqual = true;
+                            break;
+                        }
+                    }
+                    if (!isEqual) {
+                        return false;
+                    }
+                }
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void onHostDetected(Host host) {
+        log.info(HOST_DETECT, host);
+        DeviceId deviceId = host.location().deviceId();
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            log.info(NOT_MASTER_FOR_SPECIFIC_DEVICE);
+            return;
+        }
+
+        String ifaceId = host.annotations().value(IFACEID);
+        if (ifaceId == null) {
+            log.error(IFACEID_OF_HOST_IS_NULL);
+            return;
+        }
+        VpnPortId vpnPortId = VpnPortId.vpnPortId(ifaceId);
+        // Get VPN port id from EVPN app store
+        if (!vpnPortService.exists(vpnPortId)) {
+            log.info(CANT_FIND_VPN_PORT, ifaceId);
+            return;
+        }
+
+        VpnPort vpnPort = vpnPortService.getPort(vpnPortId);
+        VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+        if (!vpnInstanceService.exists(vpnInstanceId)) {
+            log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+            return;
+        }
+
+        Label privateLabel = applyLabel();
+        // create private route and get label
+        setPrivateRoute(host, vpnInstanceId, privateLabel,
+                        Objective.Operation.ADD);
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+
+        List<VpnRouteTarget> rtImport
+                = new LinkedList<>(vpnInstance.getImportRouteTargets());
+        List<VpnRouteTarget> rtExport
+                = new LinkedList<>(vpnInstance.getExportRouteTargets());
+        //download flows
+        setFlows(deviceId, host, privateLabel, rtImport,
+                 Objective.Operation.ADD);
+    }
+
+    /**
+     * update or withdraw evpn route from route admin service.
+     *
+     * @param host          host
+     * @param vpnInstanceId vpn instance id
+     * @param privateLabel  private label
+     * @param type          operation type
+     */
+    private void setPrivateRoute(Host host, VpnInstanceId vpnInstanceId,
+                                 Label privateLabel,
+                                 Operation type) {
+        DeviceId deviceId = host.location().deviceId();
+        Device device = deviceService.getDevice(deviceId);
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+        RouteDistinguisher rd = vpnInstance.routeDistinguisher();
+        Set<VpnRouteTarget> importRouteTargets
+                = vpnInstance.getImportRouteTargets();
+        Set<VpnRouteTarget> exportRouteTargets
+                = vpnInstance.getExportRouteTargets();
+        EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
+        String url = device.annotations().value(SWITCH_CHANNEL_ID);
+        String controllerIp = url.substring(0, url.lastIndexOf(":"));
+
+        if (controllerIp == null) {
+            log.error(CANT_FIND_CONTROLLER_DEVICE, device.id().toString());
+            return;
+        }
+        IpAddress ipAddress = IpAddress.valueOf(controllerIp);
+        // create private route
+        EvpnInstanceNextHop evpnNextHop = EvpnInstanceNextHop
+                .evpnNextHop(ipAddress, privateLabel);
+        EvpnInstancePrefix evpnPrefix = EvpnInstancePrefix
+                .evpnPrefix(host.mac(), IpPrefix.valueOf(host.ipAddresses()
+                                                                 .iterator()
+                                                                 .next()
+                                                                 .getIp4Address(), 32));
+        EvpnInstanceRoute evpnPrivateRoute
+                = new EvpnInstanceRoute(instanceName,
+                                        rd,
+                                        new LinkedList<>(importRouteTargets),
+                                        new LinkedList<>(exportRouteTargets),
+                                        evpnPrefix,
+                                        evpnNextHop,
+                                        IpPrefix.valueOf(host.ipAddresses()
+                                                                 .iterator()
+                                                                 .next()
+                                                                 .getIp4Address(), 32),
+                                        ipAddress,
+                                        privateLabel);
+
+        // change to public route
+        EvpnRoute evpnRoute
+                = new EvpnRoute(Source.LOCAL,
+                                host.mac(),
+                                IpPrefix.valueOf(host.ipAddresses()
+                                                         .iterator()
+                                                         .next()
+                                                         .getIp4Address(), 32),
+                                ipAddress,
+                                rd,
+                                new LinkedList<>(importRouteTargets),
+                                new LinkedList<>(exportRouteTargets),
+                                privateLabel);
+        if (type.equals(Objective.Operation.ADD)) {
+            //evpnRouteAdminService.update(Sets.newHashSet(evpnPrivateRoute));
+            evpnInstanceRoutes.add(evpnPrivateRoute);
+            evpnRouteAdminService.update(Sets.newHashSet(evpnRoute));
+
+        } else {
+            //evpnRouteAdminService.withdraw(Sets.newHashSet(evpnPrivateRoute));
+            evpnInstanceRoutes.remove(evpnPrivateRoute);
+            evpnRouteAdminService.withdraw(Sets.newHashSet(evpnRoute));
+        }
+    }
+
+    /**
+     * Generate the label for evpn route from global pool.
+     */
+    private Label applyLabel() {
+        Collection<LabelResource> privateLabels = labelService
+                .applyFromGlobalPool(1);
+        Label privateLabel = Label.label(0);
+        if (!privateLabels.isEmpty()) {
+            privateLabel = Label.label(Integer.parseInt(
+                    privateLabels.iterator().next()
+                            .labelResourceId().toString()));
+        }
+        log.info(GET_PRIVATE_LABEL, privateLabel);
+        return privateLabel;
+    }
+
+    @Override
+    public void onHostVanished(Host host) {
+        log.info(HOST_VANISHED, host);
+        DeviceId deviceId = host.location().deviceId();
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
+        }
+        String ifaceId = host.annotations().value(IFACEID);
+        if (ifaceId == null) {
+            log.error(IFACEID_OF_HOST_IS_NULL);
+            return;
+        }
+        // Get info from Gluon Shim
+        VpnPort vpnPort = vpnPortService.getPort(VpnPortId.vpnPortId(ifaceId));
+        VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+        if (!vpnInstanceService.exists(vpnInstanceId)) {
+            log.info(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+            return;
+        }
+        VpnInstance vpnInstance = vpnInstanceService.getInstance(vpnInstanceId);
+
+        Label label = releaseLabel(vpnInstance, host);
+        // create private route and get label
+        setPrivateRoute(host, vpnInstanceId, label, Objective.Operation.REMOVE);
+        // download flows
+        List<VpnRouteTarget> rtImport
+                = new LinkedList<>(vpnInstance.getImportRouteTargets());
+        List<VpnRouteTarget> rtExport
+                = new LinkedList<>(vpnInstance.getExportRouteTargets());
+        setFlows(deviceId, host, label, rtImport,
+                 Objective.Operation.REMOVE);
+    }
+
+    /**
+     * Release the label from the evpn route.
+     *
+     * @param vpnInstance vpn instance
+     * @param host        host
+     */
+    private Label releaseLabel(VpnInstance vpnInstance, Host host) {
+        EvpnInstanceName instanceName = vpnInstance.vpnInstanceName();
+
+        //Get all vpn-instance routes and check for label.
+        Label label = null;
+        for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
+            if (evpnInstanceRoute.evpnInstanceName().equals(instanceName)) {
+                label = evpnInstanceRoute.getLabel();
+                // delete private route and get label ,change to public route
+                boolean isRelease
+                        = labelService
+                        .releaseToGlobalPool(
+                                Sets.newHashSet(
+                                        LabelResourceId
+                                                .labelResourceId(label.getLabel())));
+                if (!isRelease) {
+                    log.error(RELEASE_LABEL_FAILED, label.getLabel());
+                }
+                break;
+            }
+        }
+        return label;
+    }
+
+    private class InternalRouteEventListener implements EvpnRouteListener {
+
+        @Override
+        public void event(EvpnRouteEvent event) {
+            if (!(event.subject() instanceof EvpnRoute)) {
+                return;
+            }
+            EvpnRoute route = (EvpnRoute) event.subject();
+            if (EvpnRouteEvent.Type.ROUTE_ADDED == event.type()) {
+                onBgpEvpnRouteUpdate(route);
+            } else if (EvpnRouteEvent.Type.ROUTE_REMOVED == event.type()) {
+                onBgpEvpnRouteDelete(route);
+            }
+        }
+    }
+
+    private class InnerHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (HostEvent.Type.HOST_ADDED == event.type()) {
+                onHostDetected(host);
+            } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
+                onHostVanished(host);
+            }
+        }
+
+    }
+
+    private class InnerVpnPortListener implements VpnPortListener {
+
+        @Override
+        public void event(VpnPortEvent event) {
+            VpnPort vpnPort = event.subject();
+            if (VpnPortEvent.Type.VPN_PORT_DELETE == event.type()) {
+                onVpnPortDelete(vpnPort);
+            } else if (VpnPortEvent.Type.VPN_PORT_SET == event.type()) {
+                onVpnPortSet(vpnPort);
+            }
+        }
+    }
+
+    @Override
+    public void onVpnPortDelete(VpnPort vpnPort) {
+        // delete the flows of this vpn
+        hostService.getHosts().forEach(host -> {
+            VpnPortId vpnPortId = vpnPort.id();
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+            if (!vpnInstanceService.exists(vpnInstanceId)) {
+                log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+                return;
+            }
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+            List<VpnRouteTarget> rtImport
+                    = new LinkedList<>(vpnInstance.getImportRouteTargets());
+            List<VpnRouteTarget> rtExport
+                    = new LinkedList<>(vpnInstance.getExportRouteTargets());
+
+            if (vpnPortId.vpnPortId()
+                    .equals(host.annotations().value(IFACEID))) {
+                log.info(VPN_PORT_UNBIND);
+                Label label = releaseLabel(vpnInstance, host);
+                // create private route and get label
+                DeviceId deviceId = host.location().deviceId();
+                setPrivateRoute(host, vpnInstanceId, label,
+                                Objective.Operation.REMOVE);
+                // download flows
+                setFlows(deviceId, host, label, rtImport,
+                         Objective.Operation.REMOVE);
+            }
+        });
+    }
+
+    @Override
+    public void onVpnPortSet(VpnPort vpnPort) {
+        // delete the flows of this vpn
+        hostService.getHosts().forEach(host -> {
+            VpnPortId vpnPortId = vpnPort.id();
+            VpnInstanceId vpnInstanceId = vpnPort.vpnInstanceId();
+            VpnInstance vpnInstance = vpnInstanceService
+                    .getInstance(vpnInstanceId);
+            if (vpnInstance == null) {
+                log.info("why vpn instance is null");
+                return;
+            }
+            List<VpnRouteTarget> rtImport
+                    = new LinkedList<>(vpnInstance.getImportRouteTargets());
+/*            List<VpnRouteTarget> rtExport
+                    = new LinkedList<>(vpnInstance.getExportRouteTargets());*/
+
+            if (!vpnInstanceService.exists(vpnInstanceId)) {
+                log.error(CANT_FIND_VPN_INSTANCE, vpnInstanceId);
+                return;
+            }
+
+            if (vpnPortId.vpnPortId()
+                    .equals(host.annotations().value(IFACEID))) {
+                log.info(VPN_PORT_BIND);
+                Label label = applyLabel();
+                // create private route and get label
+                DeviceId deviceId = host.location().deviceId();
+                setPrivateRoute(host, vpnInstanceId, label,
+                                Objective.Operation.ADD);
+                // download flows
+                setFlows(deviceId, host, label, rtImport,
+                         Objective.Operation.ADD);
+            }
+        });
+    }
+
+    /**
+     * process the gluon configuration and will update the configuration into
+     * vpn port service.
+     *
+     * @param action action
+     * @param key    key
+     * @param value  json node
+     */
+    private void processEtcdResponse(String action, String key, JsonNode
+            value) {
+        String[] list = key.split(SLASH);
+        String target = list[list.length - 2];
+        switch (target) {
+            case VPN_INSTANCE_TARGET:
+                VpnInstanceService vpnInstanceService
+                        = DefaultServiceDirectory
+                        .getService(VpnInstanceService.class);
+                vpnInstanceService.processGluonConfig(action, key, value);
+                break;
+            case VPN_PORT_TARGET:
+                VpnPortService vpnPortService = DefaultServiceDirectory
+                        .getService(VpnPortService.class);
+                vpnPortService.processGluonConfig(action, key, value);
+                break;
+            case VPN_AF_TARGET:
+                VpnAfConfigService vpnAfConfigService =
+                        DefaultServiceDirectory.getService(VpnAfConfigService
+                                                                   .class);
+                vpnAfConfigService.processGluonConfig(action, key, value);
+                break;
+            case BASEPORT:
+                BasePortService basePortService =
+                        DefaultServiceDirectory.getService(BasePortService
+                                                                   .class);
+                basePortService.processGluonConfig(action, key, value);
+                break;
+            default:
+                log.info("why target type is invalid {}", target);
+                log.info(INVALID_TARGET_RECEIVED);
+                break;
+        }
+    }
+
+    /**
+     * parse the gluon configuration received from network config system.
+     *
+     * @param jsonNode json node
+     * @param key      key
+     * @param action   action
+     */
+    private void parseEtcdResponse(JsonNode jsonNode,
+                                   String key,
+                                   String action) {
+        JsonNode modifyValue = null;
+        if (action.equals(SET)) {
+            modifyValue = jsonNode.get(key);
+        }
+        processEtcdResponse(action, key, modifyValue);
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalNetworkConfigListener implements
+            NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            String subject;
+            log.info(NETWORK_CONFIG_EVENT_IS_RECEIVED, event.type());
+            if (!event.configClass().equals(GluonConfig.class)) {
+                return;
+            }
+            log.info("Event is received from network configuration {}", event
+                    .type());
+            switch (event.type()) {
+                case CONFIG_UPDATED:
+                    subject = (String) event.subject();
+                    GluonConfig gluonConfig = configService
+                            .getConfig(subject, GluonConfig.class);
+                    JsonNode jsonNode = gluonConfig.node();
+                    parseEtcdResponse(jsonNode, subject, SET);
+                    break;
+                case CONFIG_REMOVED:
+                    subject = (String) event.subject();
+                    parseEtcdResponse(null, subject, DELETE);
+                    break;
+                default:
+                    log.info(INVALID_EVENT_RECEIVED);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * update import and export route target information in route admin service.
+     *
+     * @param evpnInstanceName   evpn instance name
+     * @param exportRouteTargets export route targets
+     * @param importRouteTargets import route targets
+     * @param action             action holds update or delete
+     */
+    private void updateImpExpRtInRoute(EvpnInstanceName evpnInstanceName,
+                                       Set<VpnRouteTarget> exportRouteTargets,
+                                       Set<VpnRouteTarget> importRouteTargets,
+                                       String action) {
+
+        for (EvpnInstanceRoute evpnInstanceRoute : evpnInstanceRoutes) {
+            if (evpnInstanceRoute.evpnInstanceName().equals(evpnInstanceName)) {
+                evpnInstanceRoute
+                        .setExportRtList(new LinkedList<>(exportRouteTargets));
+                evpnInstanceRoute
+                        .setImportRtList(new LinkedList<>(importRouteTargets));
+                if (action.equals(UPDATE)) {
+                    evpnInstanceRoutes.add(evpnInstanceRoute);
+                } else if (action.equals(DELETE)) {
+                    evpnInstanceRoutes.remove(evpnInstanceRoute);
+                }
+                //Get the public route and update route targets.
+                EvpnNextHop evpnNextHop = EvpnNextHop
+                        .evpnNextHop(evpnInstanceRoute.getNextHopl(),
+                                     evpnInstanceRoute.importRouteTarget(),
+                                     evpnInstanceRoute.exportRouteTarget(),
+                                     evpnInstanceRoute.getLabel());
+                Collection<EvpnRoute> evpnPublicRoutes
+                        = evpnRouteStore.getRoutesForNextHop(evpnNextHop.nextHop());
+                for (EvpnRoute pubRoute : evpnPublicRoutes) {
+                    EvpnRoute evpnPubRoute = pubRoute;
+                    if (evpnPubRoute.label().equals(evpnInstanceRoute
+                                                            .getLabel())) {
+                        evpnPubRoute
+                                .setExportRtList(new LinkedList<>(exportRouteTargets));
+                        evpnPubRoute
+                                .setImportRtList(new LinkedList<>(importRouteTargets));
+                        if (action.equals(UPDATE)) {
+                            evpnRouteAdminService.update(Sets.newHashSet(evpnPubRoute));
+                        } else if (action.equals(DELETE)) {
+                            evpnRouteAdminService
+                                    .withdraw(Sets.newHashSet(evpnPubRoute));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * update or withdraw evpn route based on vpn af configuration.
+     *
+     * @param vpnAfConfig vpn af configuration
+     * @param action      action holds update or delete
+     */
+
+    private void processEvpnRouteUpdate(VpnAfConfig vpnAfConfig,
+                                        String action) {
+        Collection<VpnInstance> instances
+                = vpnInstanceService.getInstances();
+        for (VpnInstance vpnInstance : instances) {
+            Set<VpnRouteTarget> configRouteTargets
+                    = vpnInstance.getConfigRouteTargets();
+            for (VpnRouteTarget vpnRouteTarget : configRouteTargets) {
+                if (vpnRouteTarget.equals(vpnAfConfig.routeTarget())) {
+                    Set<VpnRouteTarget> exportRouteTargets
+                            = vpnInstance.getExportRouteTargets();
+                    Set<VpnRouteTarget> importRouteTargets
+                            = vpnInstance.getImportRouteTargets();
+                    String routeTargetType = vpnAfConfig.routeTargetType();
+                    if (action.equals(UPDATE)) {
+                        vpnInstanceService
+                                .updateImpExpRouteTargets(routeTargetType,
+                                                          exportRouteTargets,
+                                                          importRouteTargets,
+                                                          vpnRouteTarget);
+                    } else if (action.equals(DELETE)) {
+                        switch (routeTargetType) {
+                            case EXPORT_EXTCOMMUNITY:
+                                exportRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            case IMPORT_EXTCOMMUNITY:
+                                importRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            case BOTH:
+                                exportRouteTargets.remove(vpnRouteTarget);
+                                importRouteTargets.remove(vpnRouteTarget);
+                                break;
+                            default:
+                                log.info(INVALID_ROUTE_TARGET_TYPE);
+                                break;
+                        }
+                    }
+                    updateImpExpRtInRoute(vpnInstance.vpnInstanceName(),
+                                          exportRouteTargets,
+                                          importRouteTargets,
+                                          action);
+                }
+            }
+        }
+    }
+
+    private class InnerVpnAfConfigListener implements VpnAfConfigListener {
+
+        @Override
+        public void event(VpnAfConfigEvent event) {
+            VpnAfConfig vpnAfConfig = event.subject();
+            if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_DELETE == event.type()) {
+                processEvpnRouteUpdate(vpnAfConfig, DELETE);
+            } else if (VpnAfConfigEvent.Type.VPN_AF_CONFIG_SET
+                    == event.type() || VpnAfConfigEvent.Type
+                    .VPN_AF_CONFIG_UPDATE == event.type()) {
+                processEvpnRouteUpdate(vpnAfConfig, UPDATE);
+            }
+        }
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java
new file mode 100755
index 0000000..8f83161
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * EVPN application that process configuration and host, vpn-port, route
+ * events.
+ */
+package org.onosproject.evpnopenflow.manager.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java
new file mode 100755
index 0000000..d93de24
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/manager/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * EVPN application that process configuration and host, vpn-port, route
+ * events.
+ */
+package org.onosproject.evpnopenflow.manager;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePort.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePort.java
new file mode 100755
index 0000000..1b2455a
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePort.java
@@ -0,0 +1,163 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Representation of a Base port.
+ */
+public interface BasePort {
+    /**
+     * Coarse classification of the type of the virtual port.
+     */
+    enum State {
+        /**
+         * Signifies that a basePort is currently active,This state mean that
+         * this basePort is available.
+         */
+        ACTIVE,
+        /**
+         * Signifies that a basePort is currently unavailable.
+         */
+        DOWN;
+    }
+
+    /**
+     * Returns the basePort identifier.
+     *
+     * @return basePort identifier
+     */
+    BasePortId portId();
+
+    /**
+     * Returns the network identifier.
+     *
+     * @return tenantNetwork identifier
+     */
+    TenantNetworkId networkId();
+
+    /**
+     * Returns the symbolic name for the basePort.
+     *
+     * @return basePort name
+     */
+    String name();
+
+    /**
+     * Returns the administrative status of the port,which is up(true) or
+     * down(false).
+     *
+     * @return true if the administrative status of the port is up
+     */
+    boolean adminStateUp();
+
+    /**
+     * Returns the state.
+     *
+     * @return state
+     */
+    String state();
+
+    /**
+     * Returns the MAC address.
+     *
+     * @return MAC Address
+     */
+    MacAddress macAddress();
+
+    /**
+     * Returns the port tenantId.
+     *
+     * @return port tenantId
+     */
+    TenantId tenantId();
+
+    /**
+     * Returns the device identifier.
+     *
+     * @return deviceId
+     */
+    DeviceId deviceId();
+
+    /**
+     * Returns the identifier of the entity that uses this port.
+     *
+     * @return deviceOwner
+     */
+    String deviceOwner();
+
+    /**
+     * Returns the basePort allowedAddressPairs.
+     *
+     * @return basePort allowedAddressPairs
+     */
+    Collection<AllowedAddressPair> allowedAddressPairs();
+
+    /**
+     * Returns set of IP addresses for the port, include the IP addresses and subnet
+     * identity.
+     *
+     * @return FixedIps Set of fixedIp
+     */
+    Set<FixedIp> fixedIps();
+
+    /**
+     * Returns the basePort bindinghostId.
+     *
+     * @return basePort bindinghostId
+     */
+    BindingHostId bindingHostId();
+
+    /**
+     * Returns the basePort bindingVnicType.
+     *
+     * @return basePort bindingVnicType
+     */
+    String bindingVnicType();
+
+    /**
+     * Returns the basePort bindingVifType.
+     *
+     * @return basePort bindingVifType
+     */
+    String bindingVifType();
+
+    /**
+     * Returns the basePort bindingvifDetail.
+     *
+     * @return basePort bindingvifDetail
+     */
+    String bindingVifDetails();
+
+    /**
+     * Returns the security groups.
+     *
+     * @return port security groups
+     */
+    Iterable<SecurityGroup> securityGroups();
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePortId.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePortId.java
new file mode 100755
index 0000000..4eb120a
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/BasePortId.java
@@ -0,0 +1,45 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a base port identifier.
+ */
+public final class BasePortId extends Identifier<String> {
+    // Public construction is prohibited
+    private BasePortId(String basePortId) {
+        super(checkNotNull(basePortId, "BasePortId cannot be null"));
+    }
+
+    public String portId() {
+        return identifier;
+    }
+
+    /**
+     * Creates a virtualPort id using the supplied portId.
+     *
+     * @param portId baseport identifier
+     * @return BasePortId
+     */
+    public static BasePortId portId(String portId) {
+        return new BasePortId(portId);
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultBasePort.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultBasePort.java
new file mode 100755
index 0000000..ec9e59e
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultBasePort.java
@@ -0,0 +1,236 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of Base port.
+ */
+public final class DefaultBasePort implements BasePort {
+    private final BasePortId id;
+    private final TenantNetworkId networkId;
+    private final Boolean adminStateUp;
+    private final String name;
+    private final String state;
+    private final MacAddress macAddress;
+    private final TenantId tenantId;
+    private final String deviceOwner;
+    private final DeviceId deviceId;
+    private final Set<FixedIp> fixedIps;
+    private final BindingHostId bindingHostId;
+    private final String bindingVnicType;
+    private final String bindingVifType;
+    private final String bindingVifDetails;
+    private final Set<AllowedAddressPair> allowedAddressPairs;
+    private final Set<SecurityGroup> securityGroups;
+
+    /**
+     * Creates a BasePort object.
+     *
+     * @param id                  the base port identifier
+     * @param networkId           the network identifier
+     * @param adminStateUp        adminStateup true or false
+     * @param strMap              the map of properties of base port
+     * @param state               base port state
+     * @param macAddress          the MAC address
+     * @param tenantId            the tenant identifier
+     * @param deviceId            the device identifier
+     * @param fixedIps            set of fixed IP
+     * @param bindingHostId       the binding host identifier
+     * @param allowedAddressPairs the collection of allowdeAddressPairs
+     * @param securityGroups      the collection of securityGroups
+     */
+    public DefaultBasePort(BasePortId id,
+                           TenantNetworkId networkId,
+                           Boolean adminStateUp,
+                           Map<String, String> strMap,
+                           String state,
+                           MacAddress macAddress,
+                           TenantId tenantId,
+                           DeviceId deviceId,
+                           Set<FixedIp> fixedIps,
+                           BindingHostId bindingHostId,
+                           Set<AllowedAddressPair> allowedAddressPairs,
+                           Set<SecurityGroup> securityGroups) {
+        this.id = id;
+        this.networkId = networkId;
+        this.adminStateUp = adminStateUp;
+        this.name = strMap.get("name");
+        this.state = state;
+        this.macAddress = macAddress;
+        this.tenantId = tenantId;
+        this.deviceOwner = strMap.get("deviceOwner");
+        this.deviceId = deviceId;
+        this.fixedIps = fixedIps;
+        this.bindingHostId = bindingHostId;
+        this.bindingVnicType = strMap.get("bindingVnicType");
+        this.bindingVifType = strMap.get("bindingVifType");
+        this.bindingVifDetails = strMap.get("bindingVifDetails");
+        this.allowedAddressPairs = allowedAddressPairs;
+        this.securityGroups = securityGroups;
+    }
+
+    @Override
+    public BasePortId portId() {
+        return id;
+    }
+
+    @Override
+    public TenantNetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public boolean adminStateUp() {
+        return adminStateUp;
+    }
+
+    @Override
+    public String state() {
+        return state;
+    }
+
+    @Override
+    public MacAddress macAddress() {
+        return macAddress;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public String deviceOwner() {
+        return deviceOwner;
+    }
+
+    @Override
+    public Collection<AllowedAddressPair> allowedAddressPairs() {
+        return allowedAddressPairs;
+    }
+
+    @Override
+    public Set<FixedIp> fixedIps() {
+        return fixedIps;
+    }
+
+    @Override
+    public BindingHostId bindingHostId() {
+        return bindingHostId;
+    }
+
+    @Override
+    public String bindingVnicType() {
+        return bindingVifType;
+    }
+
+    @Override
+    public String bindingVifType() {
+        return bindingVifType;
+    }
+
+    @Override
+    public String bindingVifDetails() {
+        return bindingVifDetails;
+    }
+
+    @Override
+    public Collection<SecurityGroup> securityGroups() {
+        return securityGroups;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, networkId, adminStateUp, name, state,
+                            macAddress, tenantId, deviceId, deviceOwner,
+                            allowedAddressPairs, fixedIps, bindingHostId,
+                            bindingVnicType, bindingVifType, bindingVifDetails,
+                            securityGroups);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultBasePort) {
+            final DefaultBasePort that = (DefaultBasePort) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.networkId, that.networkId)
+                    && Objects.equals(this.adminStateUp, that.adminStateUp)
+                    && Objects.equals(this.state, that.state)
+                    && Objects.equals(this.name, that.name)
+                    && Objects.equals(this.tenantId, that.tenantId)
+                    && Objects.equals(this.macAddress, that.macAddress)
+                    && Objects.equals(this.deviceId, that.deviceId)
+                    && Objects.equals(this.deviceOwner, that.deviceOwner)
+                    && Objects.equals(this.allowedAddressPairs,
+                                      that.allowedAddressPairs)
+                    && Objects.equals(this.fixedIps, that.fixedIps)
+                    && Objects.equals(this.bindingHostId, that.bindingHostId)
+                    && Objects.equals(this.bindingVifDetails,
+                                      that.bindingVifDetails)
+                    && Objects.equals(this.bindingVifType, that.bindingVifType)
+                    && Objects.equals(this.bindingVnicType,
+                                      that.bindingVnicType)
+                    && Objects.equals(this.securityGroups, that.securityGroups);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("network_id", networkId)
+                .add("adminStateUp", adminStateUp).add("state", state)
+                .add("name", name).add("state", state)
+                .add("macAddress", macAddress).add("tenantId", tenantId)
+                .add("deviced", deviceId).add("deviceOwner", deviceOwner)
+                .add("allowedAddressPairs", allowedAddressPairs)
+                .add("fixedIp", fixedIps).add("bindingHostId", bindingHostId)
+                .add("bindingVnicType", bindingVnicType)
+                .add("bindingVifDetails", bindingVifDetails)
+                .add("bindingVifType", bindingVifType)
+                .add("securityGroups", securityGroups).toString();
+    }
+
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnAfConfig.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnAfConfig.java
new file mode 100755
index 0000000..2481830
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnAfConfig.java
@@ -0,0 +1,87 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RT_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RT_TYPE_CANNOT_BE_NULL;
+
+/**
+ * Default implementation of VPN AF configuration.
+ */
+public class DefaultVpnAfConfig implements VpnAfConfig {
+
+    private final String exportRoutePolicy;
+    private final String importRoutePolicy;
+    private final VpnRouteTarget routeTarget;
+    private final String routeTargetType;
+
+    /**
+     * creates vpn af configuration object.
+     *
+     * @param exportRoutePolicy export route policy
+     * @param importRoutePolicy import route policy
+     * @param routeTarget       route target value
+     * @param routeTargetType   route target type
+     */
+    public DefaultVpnAfConfig(String exportRoutePolicy,
+                              String importRoutePolicy,
+                              VpnRouteTarget routeTarget,
+                              String routeTargetType) {
+        this.exportRoutePolicy = checkNotNull(exportRoutePolicy,
+                                              ID_CANNOT_BE_NULL);
+        this.importRoutePolicy = checkNotNull(importRoutePolicy,
+                                              ID_CANNOT_BE_NULL);
+        this.routeTarget = checkNotNull(routeTarget, RT_CANNOT_BE_NULL);
+        this.routeTargetType = checkNotNull(routeTargetType,
+                                            RT_TYPE_CANNOT_BE_NULL);
+    }
+
+    @Override
+    public String exportRoutePolicy() {
+        return exportRoutePolicy;
+    }
+
+    @Override
+    public String importRoutePolicy() {
+        return importRoutePolicy;
+    }
+
+    @Override
+    public VpnRouteTarget routeTarget() {
+        return routeTarget;
+    }
+
+    @Override
+    public String routeTargetType() {
+        return routeTargetType;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("exportRoutePolicy", exportRoutePolicy)
+                .add("importRoutePolicy", importRoutePolicy)
+                .add("routeTarget", routeTarget)
+                .add("routeTargetType", routeTargetType)
+                .toString();
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnInstance.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnInstance.java
new file mode 100755
index 0000000..e7f9c5d
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnInstance.java
@@ -0,0 +1,153 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onosproject.incubator.net.routing.EvpnInstanceName;
+import org.onosproject.incubator.net.routing.RouteDistinguisher;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.CONFIG_RT_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_RT_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_RT_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INSTANCE_NAME_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RD_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_DISTINGUISHER;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPNINSTANCE_NAME;
+
+/**
+ * Default implementation of VPN instance.
+ */
+public class DefaultVpnInstance implements VpnInstance {
+    private final VpnInstanceId id;
+    private final String description;
+    private final EvpnInstanceName name;
+    private final RouteDistinguisher routeDistinguisher;
+    private final Set<VpnRouteTarget> exportRtSet;
+    private final Set<VpnRouteTarget> importRtSet;
+    private final Set<VpnRouteTarget> configRtSet;
+
+
+    /**
+     * creates vpn instance object.
+     *
+     * @param id                 vpn instance identifier
+     * @param instanceName       the name of vpn instance
+     * @param description        the description of vpn instance
+     * @param routeDistinguisher the routeDistinguisher of vpn instance
+     * @param exportRtSet        the export route target information
+     * @param importRtSet        the import route target information
+     * @param configRtSet        the config route target information
+     */
+    public DefaultVpnInstance(VpnInstanceId id, EvpnInstanceName instanceName,
+                              String description,
+                              RouteDistinguisher routeDistinguisher,
+                              Set<VpnRouteTarget> exportRtSet,
+                              Set<VpnRouteTarget> importRtSet,
+                              Set<VpnRouteTarget> configRtSet) {
+        this.id = checkNotNull(id, ID_CANNOT_BE_NULL);
+        this.name = checkNotNull(instanceName, INSTANCE_NAME_CANNOT_BE_NULL);
+        this.description = checkNotNull(description,
+                                        DESCRIPTION_CANNOT_BE_NULL);
+        this.routeDistinguisher = checkNotNull(routeDistinguisher,
+                                               RD_CANNOT_BE_NULL);
+        this.exportRtSet = checkNotNull(exportRtSet, EXPORT_RT_CANNOT_BE_NULL);
+        this.importRtSet = checkNotNull(importRtSet, IMPORT_RT_CANNOT_BE_NULL);
+        this.configRtSet = checkNotNull(configRtSet, CONFIG_RT_CANNOT_BE_NULL);
+    }
+
+    @Override
+    public VpnInstanceId id() {
+        return id;
+    }
+
+    @Override
+    public String description() {
+        return description;
+    }
+
+    @Override
+    public RouteDistinguisher routeDistinguisher() {
+        return routeDistinguisher;
+    }
+
+    @Override
+    public EvpnInstanceName vpnInstanceName() {
+        return name;
+    }
+
+    @Override
+    public Set<VpnRouteTarget> getExportRouteTargets() {
+        return exportRtSet;
+    }
+
+    @Override
+    public Set<VpnRouteTarget> getImportRouteTargets() {
+        return importRtSet;
+    }
+
+    @Override
+    public Set<VpnRouteTarget> getConfigRouteTargets() {
+        return configRtSet;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name, description, routeDistinguisher,
+                            exportRtSet, importRtSet, configRtSet);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVpnInstance) {
+            final DefaultVpnInstance that = (DefaultVpnInstance) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.name, that.name)
+                    && Objects.equals(this.description, that.description)
+                    && Objects.equals(this.routeDistinguisher,
+                                      that.routeDistinguisher)
+                    && Objects.equals(this.exportRtSet, that.exportRtSet)
+                    && Objects.equals(this.importRtSet, that.importRtSet)
+                    && Objects.equals(this.configRtSet, that.configRtSet);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add(ID, id)
+                .add(DESCRIPTION, description)
+                .add(VPNINSTANCE_NAME, name)
+                .add(ROUTE_DISTINGUISHER, routeDistinguisher)
+                .add("exportRtSet", exportRtSet)
+                .add("importRtSet", importRtSet)
+                .add("configRtSet", configRtSet)
+                .toString();
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnPort.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnPort.java
new file mode 100755
index 0000000..c036a5f
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/DefaultVpnPort.java
@@ -0,0 +1,81 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID_CANNOT_BE_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_CANNOT_BE_NULL;
+
+/**
+ * Default implementation of VPN port.
+ */
+public class DefaultVpnPort implements VpnPort {
+
+    private final VpnPortId id;
+    private final VpnInstanceId vpnInstanceId;
+
+    /**
+     * creates vpn port object.
+     *
+     * @param id            vpn port id
+     * @param vpnInstanceId vpn instance id
+     */
+    public DefaultVpnPort(VpnPortId id, VpnInstanceId vpnInstanceId) {
+        this.id = checkNotNull(id, ID_CANNOT_BE_NULL);
+        this.vpnInstanceId = checkNotNull(vpnInstanceId,
+                                          VPN_INSTANCE_ID_CANNOT_BE_NULL);
+    }
+
+    @Override
+    public VpnPortId id() {
+        return id;
+    }
+
+    @Override
+    public VpnInstanceId vpnInstanceId() {
+        return vpnInstanceId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, vpnInstanceId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVpnPort) {
+            final DefaultVpnPort that = (DefaultVpnPort) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.vpnInstanceId, that.vpnInstanceId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add(ID, id)
+                .add(VPN_INSTANCE_ID, vpnInstanceId).toString();
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/EvpnConstants.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/EvpnConstants.java
new file mode 100755
index 0000000..3bb692c
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/EvpnConstants.java
@@ -0,0 +1,186 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+/**
+ * Provides constants used in EVPN openflow application.
+ */
+public final class EvpnConstants {
+    private EvpnConstants() {
+    }
+
+    public static final String APP_ID = "org.onosproject.evpnopenflow";
+    public static final String EVPN_OPENFLOW_START = "evpn-openflow app is " +
+            "started";
+    public static final String EVPN_OPENFLOW_STOP = "evpn-openflow app is " +
+            "stopped";
+    public static final String EVPN_VPN_PORT_START = "EVPN port started";
+    public static final String EVPN_VPN_PORT_STOP = "EVPN port stopped";
+    public static final String EVPN_VPN_INSTANCE_START = "EVPN instance " +
+            "started";
+    public static final String EVPN_VPN_INSTANCE_STOP = "EVPN instance " +
+            "stopped";
+    public static final String HOST_DETECT = "Host detected {}";
+    public static final String HOST_VANISHED = "Host vanished {}";
+    public static final String IFACEID = "ifaceid";
+    public static final String IFACEID_OF_HOST_IS_NULL =
+            "The ifaceId of host is null";
+    public static final String CANT_FIND_VPN_PORT = "Can't find vpnport {}";
+    public static final String CANT_FIND_VPN_INSTANCE = "EVPN instance {} is " +
+            "not exist";
+    public static final String CANT_FIND_CONTROLLER_DEVICE = "Can't find " +
+            "controller of device: {}";
+    public static final String GET_PRIVATE_LABEL = "Get private label {}";
+    public static final String RELEASE_LABEL_FAILED = "Release resoure label " +
+            "{} failed";
+    public static final String VPN_PORT_UNBIND = "On EVPN port unbind";
+    public static final String VPN_PORT_BIND = "On EVPN port bind";
+    public static final String SLASH = "/";
+    public static final String COMMA = ",";
+    public static final String VPN_INSTANCE_TARGET = "VpnService";
+    public static final String VPN_PORT_TARGET = "VpnBinding";
+    public static final String BASEPORT = "Port";
+    public static final String VPN_AF_TARGET = "VpnAfConfig";
+    public static final String BGP_PEERING = "BGPPeering";
+    public static final String DATA_PLANE_TUNNEL = "DataplaneTunnel";
+    public static final String VPN_PORT_STORE = "evpn-port-store";
+    public static final String BASE_PORT_STORE = "evpn-baseport-store";
+    public static final String VPN_INSTANCE_STORE =
+            "evpn-instance-store";
+    public static final String VPN_PORT_ID_NOT_NULL = "EVPN port ID cannot be" +
+            " null";
+    public static final String VPN_PORT_NOT_NULL = "EVPN port cannot be null";
+    public static final String RESPONSE_NOT_NULL = "JsonNode can not be null";
+    public static final String LISTENER_NOT_NULL = "Listener cannot be null";
+    public static final String EVENT_NOT_NULL = "Event cannot be null";
+    public static final String DELETE = "delete";
+    public static final String SET = "set";
+    public static final String UPDATE = "update";
+    public static final String VPN_PORT_ID = "EVPN port ID is  {} ";
+    public static final String VPN_PORT_CREATION_FAILED = "The EVPN port " +
+            "creation is failed whose identifier is {} ";
+    public static final String VPN_PORT_IS_NOT_EXIST = "The EVPN port is not " +
+            "exist whose identifier is {}";
+    public static final String VPN_PORT_UPDATE_FAILED = "The EVPN port update" +
+            " is failed whose identifier is {}";
+    public static final String VPN_PORT_DELETE_FAILED =
+            "The EVPN port delete is failed whose identifier is {}";
+    public static final String INTERFACE_ID = "interface_id";
+    public static final String ID = "id";
+    public static final String VPN_INSTANCE = "service_id";
+    public static final String VPN_INSTANCE_ID_NOT_NULL = "EVPN instance ID " +
+            "cannot be null";
+    public static final String VPN_INSTANCE_NOT_NULL = "EVPN instance cannot " +
+            "be null";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+    public static final String INSTANCE_ID = "EVPN instance ID is  {} ";
+    public static final String VPN_INSTANCE_CREATION_FAILED = "The " +
+            "EVPN instance creation is failed whose identifier is {} ";
+    public static final String VPN_INSTANCE_IS_NOT_EXIST = "The EVPN instance" +
+            " is not exist whose identifier is {}";
+    public static final String VPN_INSTANCE_UPDATE_FAILED = "The EVPN " +
+            "instance update is failed whose identifier is {}";
+    public static final String VPN_INSTANCE_DELETE_FAILED = "The EVPN " +
+            "instance delete is failed whose identifier is {}";
+    public static final String VPN_INSTANCE_NAME = "name";
+    public static final String DESCRIPTION = "description";
+    public static final String ROUTE_DISTINGUISHERS = "route_distinguishers";
+    public static final String IPV4_FAMILY = "ipv4_family";
+    static final String ID_CANNOT_BE_NULL = "ID cannot be null";
+    static final String INSTANCE_NAME_CANNOT_BE_NULL = "Instance name cannot " +
+            "be null";
+    static final String DESCRIPTION_CANNOT_BE_NULL = "Description cannot be " +
+            "null";
+    static final String RD_CANNOT_BE_NULL = "RouteDistinguisher cannot be null";
+    static final String RT_CANNOT_BE_NULL = "RouteTarget cannot be null";
+    static final String VPNINSTANCE_NAME = "vpnInstanceName";
+    static final String ROUTE_DISTINGUISHER = "routeDistinguisher";
+    static final String VPN_INSTANCE_ID_CANNOT_BE_NULL = "EVPN instance ID " +
+            "cannot be null";
+    static final String VPN_INSTANCE_ID = "vpnInstanceId";
+    public static final String FORMAT_VPN_INSTANCE = "Id=%s, description=%s,"
+            + " name=%s, routeDistinguisher=%s, routeTarget=%s";
+    public static final String FORMAT_VPN_PORT = "   EVPN port id=%-32s, " +
+            "EVPN instance id=%-18s";
+    public static final String FORMAT_PRIVATE_ROUTE = "   %-18s %-15s %-10s";
+    public static final String FORMAT_PUBLIC_ROUTE = "   %-18s %-18s %-10s";
+    public static final String SWITCH_CHANNEL_ID = "channelId";
+    public static final String NOT_MASTER_FOR_SPECIFIC_DEVICE = "The local " +
+            "controller is not master for the specified deviceId";
+    public static final String VPN_AF_CONFIG_STORE =
+            "evpn-vpn-af-config-store";
+    public static final String EVPN_VPN_AF_CONFIG_START = "EVPN af config" +
+            " started";
+    public static final String EVPN_VPN_AF_CONFIG_STOP = "EVPN af config" +
+            " stopped";
+    static final String RT_TYPE_CANNOT_BE_NULL = "Route target type " +
+            "cannot be null";
+    public static final String VPN_AF_CONFIG_NOT_NULL = "EVPN af config be " +
+            "null";
+    public static final String ROUTE_TARGET_VALUE = "Route target value is {} ";
+    public static final String VPN_AF_CONFIG_CREATION_FAILED = "The " +
+            "EVPN af config creation is failed whose route target is {} ";
+    public static final String VPN_AF_CONFIG_UPDATE_FAILED = "The EVPN af " +
+            "config update is failed whose identifier is {}";
+    public static final String VPN_AF_CONFIG_IS_NOT_EXIST = "The EVPN AF " +
+            "config is not exist whose identifier is {}";
+    public static final String ROUTE_TARGET_CANNOT_NOT_NULL = "Route target " +
+            "value cannot be null";
+    public static final String ROUTE_TARGET_DELETE_FAILED = "The route target" +
+            " delete is failed whose route target value is {}";
+    static final String EXPORT_RT_CANNOT_BE_NULL = "export route " +
+            "target set cannot be null";
+    static final String IMPORT_RT_CANNOT_BE_NULL = "import route " +
+            "target set cannot be null";
+    static final String CONFIG_RT_CANNOT_BE_NULL = "import route " +
+            "target set cannot be null";
+    public static final String EXPORT_EXTCOMMUNITY = "export_extcommunity";
+    public static final String IMPORT_EXTCOMMUNITY = "import_extcommunity";
+    public static final String BOTH = "both";
+    public static final String INVALID_ROUTE_TARGET_TYPE
+            = "Invalid route target type has received";
+    public static final String INVALID_EVENT_RECEIVED
+            = "Invalid event is received while processing network " +
+            "configuration event";
+    public static final String NETWORK_CONFIG_EVENT_IS_RECEIVED
+            = "Event is received from network configuration {}";
+    public static final int ARP_PRIORITY = 0xffff;
+    public static final short ARP_RESPONSE = 0x2;
+    public static final String INVALID_TARGET_RECEIVED
+            = "Invalid target type has received";
+    public static final String INVALID_ACTION_VPN_AF_CONFIG
+            = "Invalid action is received while processing VPN af" +
+            " configuration";
+    public static final String EXPORT_ROUTE_POLICY = "export_route_policy";
+    public static final String IMPORT_ROUTE_POLICY = "import_route_policy";
+    public static final String VRF_RT_TYPE = "vrf_rt_type";
+    public static final String VRF_RT_VALUE = "vrf_rt_value";
+    public static final String BGP_EVPN_ROUTE_UPDATE_START
+            = "bgp evpn route update start {}";
+    public static final String MPLS_OUT_FLOWS = "mpls out flows --> {}";
+    public static final String BGP_EVPN_ROUTE_DELETE_START
+            = "bgp route delete start {}";
+    public static final String ROUTE_ADD_ARP_RULES = "Route ARP Rules-->ADD";
+    public static final String ROUTE_REMOVE_ARP_RULES
+            = "Route ARP Rules-->REMOVE";
+    public static final String TUNNEL_DST = "tunnelDst";
+    public static final String FAILED_TO_SET_TUNNEL_DST
+            = "Failed to get extension instruction to set tunnel dst {}";
+    public static final String VXLAN = "vxlan";
+    public static final String CANNOT_FIND_TUNNEL_PORT_DEVICE =
+            "Can't find tunnel port in device {}";
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnAfConfig.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnAfConfig.java
new file mode 100755
index 0000000..e9bd068
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnAfConfig.java
@@ -0,0 +1,53 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+/**
+ * Representation of a VPN af configuration.
+ */
+public interface VpnAfConfig {
+
+    /**
+     * Returns the export route policy information.
+     *
+     * @return export route policy
+     */
+    String exportRoutePolicy();
+
+    /**
+     * Returns the import route policy information.
+     *
+     * @return export route policy
+     */
+    String importRoutePolicy();
+
+    /**
+     * Returns the route target value.
+     *
+     * @return route target value
+     */
+    VpnRouteTarget routeTarget();
+
+    /**
+     * Returns the route target type.
+     *
+     * @return route target type
+     */
+    String routeTargetType();
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstance.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstance.java
new file mode 100755
index 0000000..d49027b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstance.java
@@ -0,0 +1,78 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onosproject.incubator.net.routing.EvpnInstanceName;
+import org.onosproject.incubator.net.routing.RouteDistinguisher;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+import java.util.Set;
+
+/**
+ * Representation of a VPN instance.
+ */
+public interface VpnInstance {
+
+    /**
+     * Returns the VPN instance identifier.
+     *
+     * @return VPN instance identifier
+     */
+    VpnInstanceId id();
+
+    /**
+     * Returns the VPN instance description.
+     *
+     * @return VPN instance description
+     */
+    String description();
+
+    /**
+     * Returns the VPN instance route distinguishes.
+     *
+     * @return VPN instance route distinguishes
+     */
+    RouteDistinguisher routeDistinguisher();
+
+    /**
+     * Returns the VPN instance name.
+     *
+     * @return VPN instance name
+     */
+    EvpnInstanceName vpnInstanceName();
+
+    /**
+     * Returns the export route target information.
+     *
+     * @return export route target information
+     */
+    Set<VpnRouteTarget> getExportRouteTargets();
+
+    /**
+     * Returns the import route target information.
+     *
+     * @return VPN instance ipv4 family
+     */
+    Set<VpnRouteTarget> getImportRouteTargets();
+
+    /**
+     * Returns the config route target information.
+     *
+     * @return config route target information.
+     */
+    Set<VpnRouteTarget> getConfigRouteTargets();
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstanceId.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstanceId.java
new file mode 100755
index 0000000..03399ed
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnInstanceId.java
@@ -0,0 +1,48 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onlab.util.Identifier;
+
+/**
+ * Immutable representation of a VPN instance identity.
+ */
+public final class VpnInstanceId extends Identifier<String> {
+    // Public construction is prohibited
+    private VpnInstanceId(String vpnInstanceId) {
+        super(vpnInstanceId);
+    }
+
+    /**
+     * Creates a VPN instance identifier.
+     *
+     * @param vpnInstanceId VPN instance identify string
+     * @return VPN instance identifier
+     */
+    public static VpnInstanceId vpnInstanceId(String vpnInstanceId) {
+        return new VpnInstanceId(vpnInstanceId);
+    }
+
+    /**
+     * Returns VPN instance identifier.
+     *
+     * @return the VPN instance identifier
+     */
+    public String vpnInstanceId() {
+        return identifier;
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPort.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPort.java
new file mode 100755
index 0000000..82f5336
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPort.java
@@ -0,0 +1,37 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+/**
+ * Representation of a VPN port.
+ */
+public interface VpnPort {
+
+    /**
+     * Returns the VPN port identifier.
+     *
+     * @return VPN port identifier
+     */
+    VpnPortId id();
+
+    /**
+     * Returns the VPN instance identifier.
+     *
+     * @return VPN instance identifier
+     */
+    VpnInstanceId vpnInstanceId();
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPortId.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPortId.java
new file mode 100755
index 0000000..f900830
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/VpnPortId.java
@@ -0,0 +1,48 @@
+/*
+ * 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.evpnopenflow.rsc;
+
+import org.onlab.util.Identifier;
+
+/**
+ * Immutable representation of a VPN port identity.
+ */
+public final class VpnPortId extends Identifier<String> {
+    // Public construction is prohibited
+    private VpnPortId(String vpnPortId) {
+        super(vpnPortId);
+    }
+
+    /**
+     * Creates a VPN port identifier.
+     *
+     * @param vpnPortId VPN port identifier
+     * @return VPN port identifier
+     */
+    public static VpnPortId vpnPortId(String vpnPortId) {
+        return new VpnPortId(vpnPortId);
+    }
+
+    /**
+     * Returns VPN port identifier.
+     *
+     * @return the VPN port identifier
+     */
+    public String vpnPortId() {
+        return identifier;
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java
new file mode 100755
index 0000000..acb762a
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java
@@ -0,0 +1,65 @@
+/*
+ * 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.evpnopenflow.rsc.baseport;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+
+/**
+ * Describes base port event.
+ */
+public class BasePortEvent extends AbstractEvent<BasePortEvent.Type,
+        BasePort> {
+    /**
+     * Type of base port events.
+     */
+    public enum Type {
+        /**
+         * Signifies that base port has been created.
+         */
+        BASE_PORT_PUT,
+        /**
+         * Signifies that base port has been deleted.
+         */
+        BASE_PORT_DELETE,
+        /**
+         * Signifies that base port has been updated.
+         */
+        BASE_PORT_UPDATE
+    }
+
+    /**
+     * Creates an event of a given type and for the specified base port.
+     *
+     * @param type     base port event type
+     * @param basePort base port subject
+     */
+    public BasePortEvent(Type type, BasePort basePort) {
+        super(type, basePort);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified base port.
+     *
+     * @param type     base port event type
+     * @param basePort base port subject
+     * @param time     occurrence time
+     */
+    public BasePortEvent(Type type, BasePort basePort, long time) {
+        super(type, basePort, time);
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java
new file mode 100755
index 0000000..2822bb3
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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.evpnopenflow.rsc.baseport;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of base port related events.
+ */
+public interface BasePortListener extends EventListener<BasePortEvent> {
+
+}
\ No newline at end of file
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java
new file mode 100755
index 0000000..c3bdb2b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java
@@ -0,0 +1,155 @@
+/*
+ * 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.evpnopenflow.rsc.baseport;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import java.util.Collection;
+
+
+/**
+ * Service for interacting with the inventory of basePort.
+ */
+public interface BasePortService {
+    /**
+     * Returns if the basePort is existed.
+     *
+     * @param basePortId basePort identifier
+     * @return true or false if one with the given identifier is not existed.
+     */
+    boolean exists(BasePortId basePortId);
+
+    /**
+     * Returns the basePort with the identifier.
+     *
+     * @param basePortId basePort ID
+     * @return BasePort or null if one with the given ID is not know.
+     */
+    BasePort getPort(BasePortId basePortId);
+
+    /**
+     * Returns the basePort associated with the fixedIP.
+     *
+     * @param fixedIP the fixedIP identifier
+     * @return basePort.
+     */
+    BasePort getPort(FixedIp fixedIP);
+
+    /**
+     * Returns the basePort associated with the mac address.
+     *
+     * @param mac the mac address
+     * @return basePort.
+     */
+    BasePort getPort(MacAddress mac);
+
+    /**
+     * Returns the basePort associated with the networkId and ip.
+     *
+     * @param networkId the TenantNetworkId identifier
+     * @param ip        the ip identifier
+     * @return basePort.
+     */
+    BasePort getPort(TenantNetworkId networkId, IpAddress ip);
+
+    /**
+     * Returns the collection of the currently known basePort.
+     *
+     * @return collection of BasePort.
+     */
+    Collection<BasePort> getPorts();
+
+    /**
+     * Returns the collection of the basePorts associated with the networkId.
+     *
+     * @param networkId the network identifer
+     * @return collection of basePort.
+     */
+    Collection<BasePort> getPorts(TenantNetworkId networkId);
+
+    /**
+     * Returns the collection of the basePorts associated with the tenantId.
+     *
+     * @param tenantId the tenant identifier
+     * @return collection of basePorts.
+     */
+    Collection<BasePort> getPorts(TenantId tenantId);
+
+    /**
+     * Returns the collection of the basePorts associated with the deviceId.
+     *
+     * @param deviceId the device identifier
+     * @return collection of basePort.
+     */
+    Collection<BasePort> getPorts(DeviceId deviceId);
+
+    /**
+     * Creates basePorts by basePorts.
+     *
+     * @param basePorts the iterable collection of basePorts
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createPorts(Iterable<BasePort> basePorts);
+
+    /**
+     * Updates basePorts by basePorts.
+     *
+     * @param basePorts the iterable  collection of basePorts
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updatePorts(Iterable<BasePort> basePorts);
+
+    /**
+     * Deletes basePortIds by basePortIds.
+     *
+     * @param basePortIds the iterable collection of basePort identifiers
+     * @return true or false if one with the given identifier to delete is
+     * successfully.
+     */
+    boolean removePorts(Iterable<BasePortId> basePortIds);
+
+    /**
+     * process gluon config for vpn port information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the vpn port configuration
+     */
+    void processGluonConfig(String action, String key, JsonNode value);
+
+    /**
+     * Adds the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void addListener(BasePortListener listener);
+
+    /**
+     * Removes the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void removeListener(BasePortListener listener);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java
new file mode 100755
index 0000000..29c4d66
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java
@@ -0,0 +1,439 @@
+/*
+ * 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.evpnopenflow.rsc.baseport.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.evpnopenflow.rsc.DefaultBasePort;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortEvent;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortListener;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.MultiValuedTimestamp;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultFloatingIp;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.FloatingIp;
+import org.onosproject.vtnrsc.FloatingIpId;
+import org.onosproject.vtnrsc.RouterId;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.TenantRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASE_PORT_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+
+/**
+ * Provides implementation of the BasePort APIs.
+ */
+@Component(immediate = true)
+@Service
+public class BasePortManager implements BasePortService {
+
+    private final Set<BasePortListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String BASEPORT_ID_NULL = "BasePort ID cannot be " +
+            "null";
+    private static final String BASEPORT_NOT_NULL = "BasePort  cannot be " +
+            "null";
+    private static final String TENANTID_NOT_NULL = "TenantId  cannot be null";
+    private static final String NETWORKID_NOT_NULL = "NetworkId  cannot be null";
+    private static final String DEVICEID_NOT_NULL = "DeviceId  cannot be null";
+    private static final String FIXEDIP_NOT_NULL = "FixedIp  cannot be null";
+    private static final String MAC_NOT_NULL = "Mac address  cannot be null";
+    private static final String IP_NOT_NULL = "Ip  cannot be null";
+    private static final String EVENT_NOT_NULL = "event cannot be null";
+    private static final String SET = "set";
+    private static final String UPDATE = "update";
+    private static final String DELETE = "delete";
+    private static final String SLASH = "/";
+    private static final String PROTON_BASE_PORT = "Port";
+    private static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    protected EventuallyConsistentMap<BasePortId, BasePort> vPortStore;
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Activate
+    public void activate() {
+
+        appId = coreService.registerApplication(APP_ID);
+
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(MultiValuedTimestamp.class)
+                .register(TenantNetworkId.class)
+                .register(Host.class)
+                .register(TenantNetwork.class)
+                .register(TenantNetworkId.class)
+                .register(TenantId.class)
+                .register(SubnetId.class)
+                .register(BasePortId.class)
+                .register(BasePort.State.class)
+                .register(AllowedAddressPair.class)
+                .register(FixedIp.class)
+                .register(FloatingIp.class)
+                .register(FloatingIpId.class)
+                .register(FloatingIp.Status.class)
+                .register(UUID.class)
+                .register(DefaultFloatingIp.class)
+                .register(BindingHostId.class)
+                .register(SecurityGroup.class)
+                .register(IpAddress.class)
+                .register(DefaultBasePort.class)
+                .register(RouterId.class)
+                .register(TenantRouter.class)
+                .register(BasePort.class);
+        vPortStore = storageService
+                .<BasePortId, BasePort>eventuallyConsistentMapBuilder()
+                .withName(BASE_PORT_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vPortStore.destroy();
+        log.info("Stoppped");
+    }
+
+    @Override
+    public boolean exists(BasePortId vPortId) {
+        checkNotNull(vPortId, BASEPORT_ID_NULL);
+        return vPortStore.containsKey(vPortId);
+    }
+
+    @Override
+    public BasePort getPort(BasePortId vPortId) {
+        checkNotNull(vPortId, BASEPORT_ID_NULL);
+        return vPortStore.get(vPortId);
+    }
+
+    @Override
+    public BasePort getPort(FixedIp fixedIP) {
+        checkNotNull(fixedIP, FIXEDIP_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().forEach(p -> {
+            for (FixedIp fixedIp : p.fixedIps()) {
+                if (fixedIp.equals(fixedIP)) {
+                    vPorts.add(p);
+                    break;
+                }
+            }
+        });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public BasePort getPort(MacAddress mac) {
+        checkNotNull(mac, MAC_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().forEach(p -> {
+            if (p.macAddress().equals(mac)) {
+                vPorts.add(p);
+            }
+        });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public BasePort getPort(TenantNetworkId networkId, IpAddress ip) {
+        checkNotNull(networkId, NETWORKID_NOT_NULL);
+        checkNotNull(ip, IP_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
+                .forEach(p -> {
+                    for (FixedIp fixedIp : p.fixedIps()) {
+                        if (fixedIp.ip().equals(ip)) {
+                            vPorts.add(p);
+                            break;
+                        }
+                    }
+                });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public Collection<BasePort> getPorts() {
+        return Collections.unmodifiableCollection(vPortStore.values());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORKID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.networkId().equals(networkId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(TenantId tenantId) {
+        checkNotNull(tenantId, TENANTID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.tenantId().equals(tenantId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICEID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.deviceId().equals(deviceId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean createPorts(Iterable<BasePort> vPorts) {
+        checkNotNull(vPorts, BASEPORT_NOT_NULL);
+        for (BasePort vPort : vPorts) {
+            log.info("vPortId is  {} ", vPort.portId().toString());
+            vPortStore.put(vPort.portId(), vPort);
+            if (!vPortStore.containsKey(vPort.portId())) {
+                log.info("The basePort is created failed whose identifier is" +
+                                 " {} ",
+                         vPort.portId().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePorts(Iterable<BasePort> vPorts) {
+        checkNotNull(vPorts, BASEPORT_NOT_NULL);
+        for (BasePort vPort : vPorts) {
+            vPortStore.put(vPort.portId(), vPort);
+            if (!vPortStore.containsKey(vPort.portId())) {
+                log.info("The basePort is not exist whose identifier is {}",
+                         vPort.portId().toString());
+                return false;
+            }
+
+            vPortStore.put(vPort.portId(), vPort);
+
+            if (!vPort.equals(vPortStore.get(vPort.portId()))) {
+                log.info("The basePort is updated failed whose  identifier " +
+                                 "is {}",
+                         vPort.portId().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removePorts(Iterable<BasePortId> vPortIds) {
+        checkNotNull(vPortIds, BASEPORT_ID_NULL);
+        for (BasePortId vPortId : vPortIds) {
+            vPortStore.remove(vPortId);
+            if (vPortStore.containsKey(vPortId)) {
+                log.info("The basePort is removed failed whose identifier is" +
+                                 " {}",
+                         vPortId.toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns a collection of basePorts from subnetNodes.
+     *
+     * @param vPortNodes the basePort json node
+     * @return BasePort collection of vpn ports
+     */
+    private Collection<BasePort> changeJsonToSub(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Set<FixedIp> fixedIps = null;
+        TenantNetworkId tenantNetworkId = null;
+        Map<BasePortId, BasePort> vportMap = new HashMap<>();
+        Map<String, String> strMap = new HashMap<>();
+        BasePortId basePortId = BasePortId.portId(vPortNodes.get("id").asText());
+        String name = vPortNodes.get("name").asText();
+        TenantId tenantId = TenantId
+                .tenantId(vPortNodes.get("tenant_id").asText());
+        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
+        String state = vPortNodes.get("status").asText();
+        MacAddress macAddress = MacAddress
+                .valueOf(vPortNodes.get("mac_address").asText());
+        DeviceId deviceId = DeviceId
+                .deviceId(vPortNodes.get("device_id").asText());
+        String deviceOwner = vPortNodes.get("device_owner").asText();
+        BindingHostId bindingHostId = BindingHostId
+                .bindingHostId(vPortNodes.get("host_id").asText());
+        String bindingVnicType = vPortNodes.get("vnic_type").asText();
+        String bindingVifType = vPortNodes.get("vif_type").asText();
+        String bindingVifDetails = vPortNodes.get("vif_details").asText();
+        strMap.put("name", name);
+        strMap.put("deviceOwner", deviceOwner);
+        strMap.put("bindingVnicType", bindingVnicType);
+        strMap.put("bindingVifType", bindingVifType);
+        strMap.put("bindingVifDetails", bindingVifDetails);
+        BasePort prevBasePort = getPort(basePortId);
+        if (prevBasePort != null) {
+            fixedIps = prevBasePort.fixedIps();
+            tenantNetworkId = prevBasePort.networkId();
+        }
+        BasePort vPort = new DefaultBasePort(basePortId,
+                                             tenantNetworkId,
+                                             adminStateUp,
+                                             strMap, state,
+                                             macAddress, tenantId,
+                                             deviceId, fixedIps,
+                                             bindingHostId,
+                                             null,
+                                             null);
+        vportMap.put(basePortId, vPort);
+
+        return Collections.unmodifiableCollection(vportMap.values());
+    }
+
+    /**
+     * Returns BasePort State.
+     *
+     * @param state the base port state
+     * @return the basePort state
+     */
+    private BasePort.State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return BasePort.State.ACTIVE;
+        } else {
+            return BasePort.State.DOWN;
+        }
+
+    }
+
+    /**
+     * process Etcd response for port information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the port configuration
+     */
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<BasePort> basePorts;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                BasePortId basePortId
+                        = BasePortId.portId(list[list.length - 1]);
+                Set<BasePortId> basePortIds = Sets.newHashSet(basePortId);
+                removePorts(basePortIds);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                basePorts = changeJsonToSub(value);
+                createPorts(basePorts);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                basePorts = changeJsonToSub(value);
+                updatePorts(basePorts);
+                break;
+            default:
+                log.info("Invalid action is received while processing VPN " +
+                                 "port configuration");
+        }
+    }
+
+    private void parseEtcdResponse(JsonNode jsonNode,
+                                   String key,
+                                   String action) {
+        JsonNode modifyValue = null;
+        if (action.equals(SET)) {
+            modifyValue = jsonNode.get(key);
+        }
+        String[] list = key.split(SLASH);
+        String target = list[list.length - 2];
+        if (target.equals(PROTON_BASE_PORT)) {
+            processGluonConfig(action, key, modifyValue);
+        }
+    }
+
+    @Override
+    public void addListener(BasePortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(BasePortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.remove(listener);
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event vpn af config event
+     */
+    private void notifyListeners(BasePortEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> listener.event(event));
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/package-info.java
new file mode 100755
index 0000000..366dc00
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/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.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.baseport.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/package-info.java
new file mode 100755
index 0000000..52f5d0c
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/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.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.baseport;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPrivateRouteListCommand.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPrivateRouteListCommand.java
new file mode 100755
index 0000000..2122320
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPrivateRouteListCommand.java
@@ -0,0 +1,53 @@
+/*
+ * 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.evpnopenflow.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.evpnopenflow.manager.EvpnService;
+import org.onosproject.evpnopenflow.manager.impl.EvpnManager;
+import org.onosproject.incubator.net.routing.EvpnInstanceRoute;
+
+import java.util.Collection;
+
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_PRIVATE_ROUTE;
+
+/**
+ * Support for displaying EVPN private routes.
+ */
+@Command(scope = "onos", name = "evpn-private-routes", description = "Lists" +
+        " all EVPN private routes")
+public class EvpnPrivateRouteListCommand extends AbstractShellCommand {
+    private static final String FORMAT_HEADER =
+            "   VPN name            Prefix         Next Hop";
+
+    @Override
+    protected void execute() {
+        EvpnService service = AbstractShellCommand.get(EvpnService.class);
+        EvpnManager evpnManager = (EvpnManager) service;
+        Collection<EvpnInstanceRoute> evpnRoutes = evpnManager.evpnInstanceRoutes;
+        if (evpnRoutes != null) {
+            print(FORMAT_HEADER);
+            evpnRoutes.forEach(evpnInstanceRoute -> {
+                print(FORMAT_PRIVATE_ROUTE, evpnInstanceRoute.evpnInstanceName(),
+                      evpnInstanceRoute.prefix().address().getIp4Address(), evpnInstanceRoute
+                              .getNextHopl());
+            });
+        }
+    }
+
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPublicRouteListCommand.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPublicRouteListCommand.java
new file mode 100755
index 0000000..3067257
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/EvpnPublicRouteListCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.evpnopenflow.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.routing.EvpnRoute;
+import org.onosproject.incubator.net.routing.EvpnRouteSet;
+import org.onosproject.incubator.net.routing.EvpnRouteStore;
+
+import java.util.Collection;
+
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_PUBLIC_ROUTE;
+
+/**
+ * Support for displaying EVPN public routes.
+ */
+@Command(scope = "onos", name = "evpn-public-routes", description = "Lists" +
+        " all EVPN public routes")
+public class EvpnPublicRouteListCommand extends AbstractShellCommand {
+    private static final String FORMAT_HEADER =
+            "   MAC                  Prefix          Next Hop";
+
+    @Override
+    protected void execute() {
+        EvpnRouteStore evpnRouteStore = AbstractShellCommand.get(EvpnRouteStore.class);
+
+        evpnRouteStore.getRouteTables().forEach(routeTableId -> {
+            Collection<EvpnRouteSet> routes
+                    = evpnRouteStore.getRoutes(routeTableId);
+            if (routes != null) {
+                routes.forEach(route -> {
+                    Collection<EvpnRoute> evpnRoutes = route.routes();
+                    print(FORMAT_HEADER);
+                    evpnRoutes.forEach(evpnRoute -> {
+                        print(FORMAT_PUBLIC_ROUTE, evpnRoute.prefixMac(),
+                              evpnRoute.prefixIp().address().getIp4Address(),
+                              evpnRoute.ipNextHop());
+                    });
+                });
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnInstListCommand.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnInstListCommand.java
new file mode 100755
index 0000000..320c848
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnInstListCommand.java
@@ -0,0 +1,49 @@
+/*
+ * 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.evpnopenflow.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.evpnopenflow.rsc.EvpnConstants;
+import org.onosproject.evpnopenflow.rsc.VpnInstance;
+import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
+
+import java.util.Collection;
+
+/**
+ * Support for displaying EVPN VPN instances.
+ */
+@Command(scope = "onos", name = "evpn-instance-list", description = "Lists " +
+        "all EVPN instances")
+public class VpnInstListCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        VpnInstanceService service = get(VpnInstanceService.class);
+        Collection<VpnInstance> vpnInstances = service
+                .getInstances();
+        vpnInstances.forEach(vpnInstance -> {
+            print(EvpnConstants.FORMAT_VPN_INSTANCE, vpnInstance.id(),
+                  vpnInstance.description(),
+                  vpnInstance.vpnInstanceName(),
+                  vpnInstance.routeDistinguisher(),
+                  vpnInstance.getExportRouteTargets(),
+                  vpnInstance.getImportRouteTargets());
+        });
+    }
+
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnPortListCommand.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnPortListCommand.java
new file mode 100755
index 0000000..366ead5
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/VpnPortListCommand.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.evpnopenflow.rsc.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
+
+import java.util.Collection;
+
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.FORMAT_VPN_PORT;
+
+/**
+ * Support for displaying EVPN VPN ports.
+ */
+@Command(scope = "onos", name = "evpn-port-list", description = "Lists all" +
+        "EVPN ports")
+public class VpnPortListCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        VpnPortService portService = get(VpnPortService.class);
+        Collection<VpnPort> ports = portService.getPorts();
+        ports.forEach(port -> {
+            print(FORMAT_VPN_PORT, port.id(), port.vpnInstanceId());
+        });
+    }
+
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/package-info.java
new file mode 100755
index 0000000..3bc47c8
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/cli/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.
+ */
+
+/**
+ * Implementation CLI for EVPN services.
+ */
+package org.onosproject.evpnopenflow.rsc.cli;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/package-info.java
new file mode 100755
index 0000000..c37dc81
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/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.
+ */
+
+/**
+ * EVPN resource package.
+ */
+package org.onosproject.evpnopenflow.rsc;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigEvent.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigEvent.java
new file mode 100755
index 0000000..944698c
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigEvent.java
@@ -0,0 +1,65 @@
+/*
+ * 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.evpnopenflow.rsc.vpnafconfig;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+
+/**
+ * Describes network VPN af config event.
+ */
+public class VpnAfConfigEvent extends AbstractEvent<VpnAfConfigEvent.Type, VpnAfConfig> {
+
+    /**
+     * Type of VPN port events.
+     */
+    public enum Type {
+        /**
+         * Signifies that VPN af config has been set.
+         */
+        VPN_AF_CONFIG_SET,
+        /**
+         * Signifies that VPN af config has been deleted.
+         */
+        VPN_AF_CONFIG_DELETE,
+        /**
+         * Signifies that VPN af config has been updated.
+         */
+        VPN_AF_CONFIG_UPDATE
+    }
+
+    /**
+     * Creates an event of a given type and for the specified VPN af config.
+     *
+     * @param type        VPN af config type
+     * @param vpnAfConfig VPN af config subject
+     */
+    public VpnAfConfigEvent(Type type, VpnAfConfig vpnAfConfig) {
+        super(type, vpnAfConfig);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified VPN af config.
+     *
+     * @param type        VPN af config type
+     * @param vpnAfConfig VPN af config subject
+     * @param time        occurrence time
+     */
+    public VpnAfConfigEvent(Type type, VpnAfConfig vpnAfConfig, long time) {
+        super(type, vpnAfConfig, time);
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigListener.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigListener.java
new file mode 100755
index 0000000..42db841
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.evpnopenflow.rsc.vpnafconfig;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of VPN af config related events.
+ */
+public interface VpnAfConfigListener extends EventListener<VpnAfConfigEvent> {
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigService.java
new file mode 100755
index 0000000..31714ad
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/VpnAfConfigService.java
@@ -0,0 +1,100 @@
+/*
+ * 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.evpnopenflow.rsc.vpnafconfig;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+import java.util.Collection;
+
+/**
+ * Service for interacting with the inventory of VPN af config instance.
+ */
+public interface VpnAfConfigService {
+    /**
+     * Returns if the route target is existed.
+     *
+     * @param routeTarget route target
+     * @return true or false if one with the given route target is not existed.
+     */
+    boolean exists(VpnRouteTarget routeTarget);
+
+    /**
+     * Returns the VPN af config with the route target.
+     *
+     * @param routeTarget route target
+     * @return VPN af config or null if one with the given route target is not
+     * know.
+     */
+    VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget);
+
+    /**
+     * Returns the collection of the currently known VPN af configurations.
+     *
+     * @return collection of VPN af configurations.
+     */
+    Collection<VpnAfConfig> getVpnAfConfigs();
+
+    /**
+     * Creates VPN af configurations by vpnAfConfigs.
+     *
+     * @param vpnAfConfigs the iterable collection of vpnAfConfigs
+     * @return true if all given VPN af configs created successfully
+     */
+    boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs);
+
+    /**
+     * Updates VPN af configurations by vpnAfConfigs.
+     *
+     * @param vpnAfConfigs the iterable collection of vpnAfConfigs
+     * @return true if all given VPN af configs created successfully.
+     */
+    boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs);
+
+    /**
+     * Deletes vpnAfConfigs by route target.
+     *
+     * @param routeTarget the iterable collection of vpnAFConfigs
+     * @return true or false if one with the given route target to delete is
+     * successfully
+     */
+    boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTarget);
+
+    /**
+     * process gluon config for vpn af configuration.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the route targets configuration
+     */
+    void processGluonConfig(String action, String key, JsonNode value);
+
+    /**
+     * Adds the specified listener to Vpn Port manager.
+     *
+     * @param listener vpn af config listener
+     */
+    void addListener(VpnAfConfigListener listener);
+
+    /**
+     * Removes the specified listener to vpn af config manager.
+     *
+     * @param listener vpn af config listener
+     */
+    void removeListener(VpnAfConfigListener listener);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/VpnAfConfigManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/VpnAfConfigManager.java
new file mode 100755
index 0000000..fafd5d8
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/VpnAfConfigManager.java
@@ -0,0 +1,268 @@
+/*
+ * 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.evpnopenflow.rsc.vpnafconfig.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.DefaultVpnAfConfig;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_ROUTE_POLICY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_ROUTE_POLICY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ACTION_VPN_AF_CONFIG;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_CANNOT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_DELETE_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_VALUE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_CREATION_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_IS_NOT_EXIST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_UPDATE_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_TYPE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_VALUE;
+
+/**
+ * Provides implementation of the VPN af config APIs.
+ */
+@Component(immediate = true)
+@Service
+public class VpnAfConfigManager implements VpnAfConfigService {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final Set<VpnAfConfigListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+
+    protected EventuallyConsistentMap<VpnRouteTarget, VpnAfConfig>
+            vpnAfConfigStore;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(APP_ID);
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API).register(VpnAfConfig.class)
+                .register(VpnRouteTarget.class);
+        vpnAfConfigStore = storageService
+                .<VpnRouteTarget, VpnAfConfig>eventuallyConsistentMapBuilder()
+                .withName(VPN_AF_CONFIG_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info(EVPN_VPN_AF_CONFIG_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vpnAfConfigStore.destroy();
+        log.info(EVPN_VPN_AF_CONFIG_STOP);
+    }
+
+    @Override
+    public boolean exists(VpnRouteTarget routeTarget) {
+        checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
+        return vpnAfConfigStore.containsKey(routeTarget);
+    }
+
+    @Override
+    public VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget) {
+        checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
+        return vpnAfConfigStore.get(routeTarget);
+    }
+
+    @Override
+    public Collection<VpnAfConfig> getVpnAfConfigs() {
+        return Collections.unmodifiableCollection(vpnAfConfigStore.values());
+    }
+
+    @Override
+    public boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
+        checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
+        for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
+            log.info(ROUTE_TARGET_VALUE, vpnAfConfig
+                    .routeTarget().getRouteTarget());
+            vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
+            if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
+                log.info(VPN_AF_CONFIG_CREATION_FAILED,
+                         vpnAfConfig.routeTarget().getRouteTarget());
+                return false;
+            }
+            notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
+                                                         .Type
+                                                         .VPN_AF_CONFIG_SET,
+                                                 vpnAfConfig));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
+        checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
+        for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
+            if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
+                log.info(VPN_AF_CONFIG_IS_NOT_EXIST,
+                         vpnAfConfig.routeTarget().getRouteTarget());
+                return false;
+            }
+            vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
+            if (!vpnAfConfig.equals(vpnAfConfigStore
+                                            .get(vpnAfConfig.routeTarget()))) {
+                log.info(VPN_AF_CONFIG_UPDATE_FAILED,
+                         vpnAfConfig.routeTarget().getRouteTarget());
+                return false;
+            }
+            notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
+                                                         .Type
+                                                         .VPN_AF_CONFIG_UPDATE,
+                                                 vpnAfConfig));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTargets) {
+        checkNotNull(routeTargets, VPN_INSTANCE_ID_NOT_NULL);
+        for (VpnRouteTarget routeTarget : routeTargets) {
+            VpnAfConfig vpnAfConfig = vpnAfConfigStore.get(routeTarget);
+            vpnAfConfigStore.remove(routeTarget);
+            if (vpnAfConfigStore.containsKey(routeTarget)) {
+                log.info(ROUTE_TARGET_DELETE_FAILED,
+                         routeTarget.getRouteTarget());
+                return false;
+            }
+            notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
+                                                         .Type
+                                                         .VPN_AF_CONFIG_DELETE,
+                                                 vpnAfConfig));
+        }
+        return true;
+    }
+
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<VpnAfConfig> vpnAfConfigs;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                VpnRouteTarget routeTarget = VpnRouteTarget
+                        .routeTarget(list[list.length - 1]);
+                Set<VpnRouteTarget> routeTargets
+                        = Sets.newHashSet(routeTarget);
+                removeVpnAfConfigs(routeTargets);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnAfConfigs = changeJsonToSub(value);
+                createVpnAfConfigs(vpnAfConfigs);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnAfConfigs = changeJsonToSub(value);
+                updateVpnAfConfigs(vpnAfConfigs);
+                break;
+            default:
+                log.info(INVALID_ACTION_VPN_AF_CONFIG);
+                break;
+        }
+    }
+
+    /**
+     * Returns a collection of vpn af configuration.
+     *
+     * @param vpnAfConfigNode the vpn af configuration json node
+     * @return returns the collection of vpn af configuration
+     */
+    private Collection<VpnAfConfig> changeJsonToSub(JsonNode vpnAfConfigNode) {
+        checkNotNull(vpnAfConfigNode, JSON_NOT_NULL);
+        Map<VpnRouteTarget, VpnAfConfig> vpnAfConfigMap = new HashMap<>();
+        String exportRoutePolicy
+                = vpnAfConfigNode.get(EXPORT_ROUTE_POLICY).asText();
+        String importRoutePolicy
+                = vpnAfConfigNode.get(IMPORT_ROUTE_POLICY).asText();
+        String routeTargetType = vpnAfConfigNode.get(VRF_RT_TYPE).asText();
+        VpnRouteTarget routeTarget = VpnRouteTarget
+                .routeTarget(vpnAfConfigNode.get(VRF_RT_VALUE).asText());
+
+        VpnAfConfig vpnAfConfig = new DefaultVpnAfConfig(exportRoutePolicy,
+                                                         importRoutePolicy,
+                                                         routeTarget,
+                                                         routeTargetType);
+        vpnAfConfigMap.put(routeTarget, vpnAfConfig);
+
+        return Collections.unmodifiableCollection(vpnAfConfigMap.values());
+    }
+
+    @Override
+    public void addListener(VpnAfConfigListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(VpnAfConfigListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.remove(listener);
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event vpn af config event
+     */
+    private void notifyListeners(VpnAfConfigEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> listener.event(event));
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/package-info.java
new file mode 100755
index 0000000..f2dd128
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/impl/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.
+ */
+
+/**
+ * VPN af configuration that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpnafconfig.impl;
\ No newline at end of file
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/package-info.java
new file mode 100755
index 0000000..7c2e4f4
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnafconfig/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.
+ */
+
+/**
+ * VPN resources that used by Evpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpnafconfig;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/VpnInstanceService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/VpnInstanceService.java
new file mode 100755
index 0000000..f233f29
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/VpnInstanceService.java
@@ -0,0 +1,100 @@
+/*
+ * 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.evpnopenflow.rsc.vpninstance;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.evpnopenflow.rsc.VpnInstance;
+import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Service for interacting with the inventory of VPN instance.
+ */
+public interface VpnInstanceService {
+    /**
+     * Returns if the vpnInstance is existed.
+     *
+     * @param vpnInstanceId vpnInstance identifier
+     * @return true or false if one with the given identifier is not existed.
+     */
+    boolean exists(VpnInstanceId vpnInstanceId);
+
+    /**
+     * Returns the vpnInstance with the identifier.
+     *
+     * @param vpnInstanceId vpnInstance ID
+     * @return VpnInstance or null if one with the given ID is not know.
+     */
+    VpnInstance getInstance(VpnInstanceId vpnInstanceId);
+
+    /**
+     * Returns the collection of the currently known vpnInstance.
+     *
+     * @return collection of VpnInstance.
+     */
+    Collection<VpnInstance> getInstances();
+
+    /**
+     * Creates vpnInstances by vpnInstances.
+     *
+     * @param vpnInstances the iterable collection of vpnInstances
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createInstances(Iterable<VpnInstance> vpnInstances);
+
+    /**
+     * Updates vpnInstances by vpnInstances.
+     *
+     * @param vpnInstances the iterable  collection of vpnInstances
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updateInstances(Iterable<VpnInstance> vpnInstances);
+
+    /**
+     * Deletes vpnInstanceIds by vpnInstanceIds.
+     *
+     * @param vpnInstanceIds the iterable collection of vpnInstance identifiers
+     * @return true or false if one with the given identifier to delete is
+     * successfully.
+     */
+    boolean removeInstances(Iterable<VpnInstanceId> vpnInstanceIds);
+
+    /**
+     * process gluon config for vpn instance information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the vpn instance configuration
+     */
+    void processGluonConfig(String action, String key, JsonNode value);
+
+    /**
+     * process Etcd response for vpn instance information.
+     *
+     * @param routeTargetType    route target type
+     * @param exportRouteTargets export route targets
+     * @param importRouteTargets import route targets
+     * @param vpnRouteTarget     vpn route target
+     */
+    void updateImpExpRouteTargets(String routeTargetType,
+                                  Set<VpnRouteTarget> exportRouteTargets,
+                                  Set<VpnRouteTarget> importRouteTargets,
+                                  VpnRouteTarget vpnRouteTarget);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/VpnInstanceManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/VpnInstanceManager.java
new file mode 100755
index 0000000..361bad4
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/VpnInstanceManager.java
@@ -0,0 +1,290 @@
+/*
+ * 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.evpnopenflow.rsc.vpninstance.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.DefaultVpnInstance;
+import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
+import org.onosproject.evpnopenflow.rsc.VpnInstance;
+import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
+import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
+import org.onosproject.evpnopenflow.rsc.vpninstance.VpnInstanceService;
+import org.onosproject.incubator.net.routing.EvpnInstanceName;
+import org.onosproject.incubator.net.routing.RouteAdminService;
+import org.onosproject.incubator.net.routing.RouteDistinguisher;
+import org.onosproject.incubator.net.routing.VpnRouteTarget;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.COMMA;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DESCRIPTION;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_INSTANCE_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_INSTANCE_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INSTANCE_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IPV4_FAMILY;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_DISTINGUISHERS;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_CREATION_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_DELETE_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_IS_NOT_EXIST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_NAME;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_UPDATE_FAILED;
+
+
+/**
+ * Provides implementation of the VpnInstance APIs.
+ */
+@Component(immediate = true)
+@Service
+public class VpnInstanceManager implements VpnInstanceService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    protected EventuallyConsistentMap<VpnInstanceId, VpnInstance> vpnInstanceStore;
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteAdminService routeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VpnAfConfigService vpnAfConfigService;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API).register(VpnInstance.class)
+                .register(VpnInstanceId.class);
+        vpnInstanceStore = storageService
+                .<VpnInstanceId, VpnInstance>eventuallyConsistentMapBuilder()
+                .withName(VPN_INSTANCE_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info(EVPN_VPN_INSTANCE_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vpnInstanceStore.destroy();
+        log.info(EVPN_VPN_INSTANCE_STOP);
+    }
+
+    @Override
+    public boolean exists(VpnInstanceId vpnInstanceId) {
+        checkNotNull(vpnInstanceId, VPN_INSTANCE_ID_NOT_NULL);
+        return vpnInstanceStore.containsKey(vpnInstanceId);
+    }
+
+    @Override
+    public VpnInstance getInstance(VpnInstanceId vpnInstanceId) {
+        checkNotNull(vpnInstanceId, VPN_INSTANCE_ID_NOT_NULL);
+        return vpnInstanceStore.get(vpnInstanceId);
+    }
+
+    @Override
+    public Collection<VpnInstance> getInstances() {
+        return Collections.unmodifiableCollection(vpnInstanceStore.values());
+    }
+
+    @Override
+    public boolean createInstances(Iterable<VpnInstance> vpnInstances) {
+        checkNotNull(vpnInstances, VPN_INSTANCE_NOT_NULL);
+        for (VpnInstance vpnInstance : vpnInstances) {
+            log.info(INSTANCE_ID, vpnInstance.id().toString());
+            vpnInstanceStore.put(vpnInstance.id(), vpnInstance);
+            if (!vpnInstanceStore.containsKey(vpnInstance.id())) {
+                log.info(VPN_INSTANCE_CREATION_FAILED,
+                         vpnInstance.id().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateInstances(Iterable<VpnInstance> vpnInstances) {
+        checkNotNull(vpnInstances, VPN_INSTANCE_NOT_NULL);
+        for (VpnInstance vpnInstance : vpnInstances) {
+            if (!vpnInstanceStore.containsKey(vpnInstance.id())) {
+                log.info(VPN_INSTANCE_IS_NOT_EXIST,
+                         vpnInstance.id().toString());
+                return false;
+            }
+            vpnInstanceStore.put(vpnInstance.id(), vpnInstance);
+            if (!vpnInstance.equals(vpnInstanceStore.get(vpnInstance.id()))) {
+                log.info(VPN_INSTANCE_UPDATE_FAILED,
+                         vpnInstance.id().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeInstances(Iterable<VpnInstanceId> vpnInstanceIds) {
+        checkNotNull(vpnInstanceIds, VPN_INSTANCE_ID_NOT_NULL);
+        for (VpnInstanceId vpnInstanceId : vpnInstanceIds) {
+            vpnInstanceStore.remove(vpnInstanceId);
+            if (vpnInstanceStore.containsKey(vpnInstanceId)) {
+                log.info(VPN_INSTANCE_DELETE_FAILED, vpnInstanceId.toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<VpnInstance> vpnInstances;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                VpnInstanceId vpnInstanceId = VpnInstanceId
+                        .vpnInstanceId(list[list.length - 1]);
+                Set<VpnInstanceId> vpnInstanceIds
+                        = Sets.newHashSet(vpnInstanceId);
+                removeInstances(vpnInstanceIds);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnInstances = changeJsonToSub(value);
+                createInstances(vpnInstances);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnInstances = changeJsonToSub(value);
+                updateInstances(vpnInstances);
+                break;
+            default:
+                log.info("Invalid action is received while processing VPN " +
+                                 "instance configuration");
+        }
+    }
+
+    @Override
+    public void updateImpExpRouteTargets(String routeTargetType,
+                                         Set<VpnRouteTarget> exportRouteTargets,
+                                         Set<VpnRouteTarget> importRouteTargets,
+                                         VpnRouteTarget vpnRouteTarget) {
+        switch (routeTargetType) {
+            case "export_extcommunity":
+                exportRouteTargets.add(vpnRouteTarget);
+                break;
+            case "import_extcommunity":
+                importRouteTargets.add(vpnRouteTarget);
+                break;
+            case "both":
+                exportRouteTargets.add(vpnRouteTarget);
+                importRouteTargets.add(vpnRouteTarget);
+                break;
+            default:
+                log.info("Invalid route target type has received");
+                break;
+        }
+    }
+
+    /**
+     * Returns a collection of vpnInstances from subnetNodes.
+     *
+     * @param vpnInstanceNodes the vpnInstance json node
+     * @return returns the collection of vpn instances
+     */
+    private Collection<VpnInstance> changeJsonToSub(JsonNode vpnInstanceNodes) {
+        checkNotNull(vpnInstanceNodes, JSON_NOT_NULL);
+
+        Set<VpnRouteTarget> exportRouteTargets = new HashSet<>();
+        Set<VpnRouteTarget> importRouteTargets = new HashSet<>();
+        Set<VpnRouteTarget> configRouteTargets = new HashSet<>();
+
+        Map<VpnInstanceId, VpnInstance> vpnInstanceMap = new HashMap<>();
+        VpnInstanceId id = VpnInstanceId
+                .vpnInstanceId(vpnInstanceNodes.get(ID).asText());
+        EvpnInstanceName name = EvpnInstanceName
+                .evpnName(vpnInstanceNodes.get(VPN_INSTANCE_NAME).asText());
+        String description = vpnInstanceNodes.get(DESCRIPTION).asText();
+        RouteDistinguisher routeDistinguisher = RouteDistinguisher
+                .routeDistinguisher(vpnInstanceNodes.get(ROUTE_DISTINGUISHERS)
+                                            .asText());
+        String routeTargets = vpnInstanceNodes.get(IPV4_FAMILY).asText();
+        String[] list = routeTargets.split(COMMA);
+
+        for (String routeTarget : list) {
+            // Converting route target string into route target object and
+            // then storing into configuration route target set.
+            VpnRouteTarget vpnRouteTarget
+                    = VpnRouteTarget.routeTarget(routeTarget);
+            configRouteTargets.add(vpnRouteTarget);
+            VpnAfConfig vpnAfConfig
+                    = vpnAfConfigService.getVpnAfConfig(vpnRouteTarget);
+            if (vpnAfConfig == null) {
+                log.info("Not able to find vpn af config for the give vpn " +
+                                 "route target");
+                break;
+            }
+            updateImpExpRouteTargets(vpnAfConfig.routeTargetType(),
+                                     exportRouteTargets,
+                                     importRouteTargets,
+                                     vpnRouteTarget);
+        }
+
+        VpnInstance vpnInstance = new DefaultVpnInstance(id, name, description,
+                                                         routeDistinguisher,
+                                                         exportRouteTargets,
+                                                         importRouteTargets,
+                                                         configRouteTargets);
+        vpnInstanceMap.put(id, vpnInstance);
+        return Collections.unmodifiableCollection(vpnInstanceMap.values());
+    }
+}
\ No newline at end of file
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/package-info.java
new file mode 100755
index 0000000..6cfc75e
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/impl/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.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpninstance.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/package-info.java
new file mode 100755
index 0000000..b68dbd0
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpninstance/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.
+ */
+
+/**
+ * EVPN VPN instance implementation.
+ */
+package org.onosproject.evpnopenflow.rsc.vpninstance;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortEvent.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortEvent.java
new file mode 100755
index 0000000..acc28db
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortEvent.java
@@ -0,0 +1,65 @@
+/*
+ * 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.evpnopenflow.rsc.vpnport;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+
+/**
+ * Describes network VPN port event.
+ */
+public class VpnPortEvent extends AbstractEvent<VpnPortEvent.Type, VpnPort> {
+
+    /**
+     * Type of VPN port events.
+     */
+    public enum Type {
+        /**
+         * Signifies that VPN port has been set.
+         */
+        VPN_PORT_SET,
+        /**
+         * Signifies that VPN port has been deleted.
+         */
+        VPN_PORT_DELETE,
+        /**
+         * Signifies that VPN port has been updated.
+         */
+        VPN_PORT_UPDATE
+    }
+
+    /**
+     * Creates an event of a given type and for the specified VPN port.
+     *
+     * @param type    VPN port type
+     * @param vpnPort VPN port subject
+     */
+    public VpnPortEvent(Type type, VpnPort vpnPort) {
+        super(type, vpnPort);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified VPN port.
+     *
+     * @param type    VPN port type
+     * @param vpnPort VPN port subject
+     * @param time    occurrence time
+     */
+    public VpnPortEvent(Type type, VpnPort vpnPort, long time) {
+        super(type, vpnPort, time);
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortListener.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortListener.java
new file mode 100755
index 0000000..95eb797
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.evpnopenflow.rsc.vpnport;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of VPN port related events.
+ */
+public interface VpnPortListener extends EventListener<VpnPortEvent> {
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortService.java
new file mode 100755
index 0000000..c7bce1b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/VpnPortService.java
@@ -0,0 +1,100 @@
+/*
+ * 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.evpnopenflow.rsc.vpnport;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnPortId;
+
+import java.util.Collection;
+
+
+/**
+ * Service for interacting with the inventory of VPN port.
+ */
+public interface VpnPortService {
+    /**
+     * Returns if the vpnPort is existed.
+     *
+     * @param vpnPortId vpnPort identifier
+     * @return true or false if one with the given identifier is not existed.
+     */
+    boolean exists(VpnPortId vpnPortId);
+
+    /**
+     * Returns the vpnPort with the identifier.
+     *
+     * @param vpnPortId vpnPort ID
+     * @return VpnPort or null if one with the given ID is not know.
+     */
+    VpnPort getPort(VpnPortId vpnPortId);
+
+    /**
+     * Returns the collection of the currently known vpnPort.
+     *
+     * @return collection of VpnPort.
+     */
+    Collection<VpnPort> getPorts();
+
+    /**
+     * Creates vpnPorts by vpnPorts.
+     *
+     * @param vpnPorts the iterable collection of vpnPorts
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createPorts(Iterable<VpnPort> vpnPorts);
+
+    /**
+     * Updates vpnPorts by vpnPorts.
+     *
+     * @param vpnPorts the iterable  collection of vpnPorts
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updatePorts(Iterable<VpnPort> vpnPorts);
+
+    /**
+     * Deletes vpnPortIds by vpnPortIds.
+     *
+     * @param vpnPortIds the iterable collection of vpnPort identifiers
+     * @return true or false if one with the given identifier to delete is
+     * successfully.
+     */
+    boolean removePorts(Iterable<VpnPortId> vpnPortIds);
+
+    /**
+     * process gluon config for vpn port information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the vpn port configuration
+     */
+    void processGluonConfig(String action, String key, JsonNode value);
+
+    /**
+     * Adds the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void addListener(VpnPortListener listener);
+
+    /**
+     * Removes the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void removeListener(VpnPortListener listener);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java
new file mode 100755
index 0000000..18ff172
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/VpnPortManager.java
@@ -0,0 +1,431 @@
+/*
+ * 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.evpnopenflow.rsc.vpnport.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.evpnopenflow.rsc.DefaultVpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnInstanceId;
+import org.onosproject.evpnopenflow.rsc.VpnPort;
+import org.onosproject.evpnopenflow.rsc.VpnPortId;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortEvent;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortListener;
+import org.onosproject.evpnopenflow.rsc.vpnport.VpnPortService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtnrsc.AllocationPool;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultSubnet;
+import org.onosproject.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.HostRoute;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.subnet.SubnetService;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_START;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_PORT_STOP;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INTERFACE_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_CREATION_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_DELETE_FAILED;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_ID_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_IS_NOT_EXIST;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_PORT_UPDATE_FAILED;
+
+/**
+ * Provides implementation of the VpnPort service.
+ */
+@Component(immediate = true)
+@Service
+public class VpnPortManager implements VpnPortService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final Set<VpnPortListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+
+    protected EventuallyConsistentMap<VpnPortId, VpnPort> vpnPortStore;
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected BasePortService basePortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualPortService virtualPortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService tenantNetworkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SubnetService subnetService;
+
+    @Activate
+
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API).register(VpnPort.class)
+                .register(VpnPortId.class);
+        vpnPortStore = storageService
+                .<VpnPortId, VpnPort>eventuallyConsistentMapBuilder()
+                .withName(VPN_PORT_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info(EVPN_VPN_PORT_START);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vpnPortStore.destroy();
+        log.info(EVPN_VPN_PORT_STOP);
+    }
+
+    @Override
+    public boolean exists(VpnPortId vpnPortId) {
+        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
+        return vpnPortStore.containsKey(vpnPortId);
+    }
+
+    @Override
+    public VpnPort getPort(VpnPortId vpnPortId) {
+        checkNotNull(vpnPortId, VPN_PORT_ID_NOT_NULL);
+        return vpnPortStore.get(vpnPortId);
+    }
+
+    @Override
+    public Collection<VpnPort> getPorts() {
+        return Collections.unmodifiableCollection(vpnPortStore.values());
+    }
+
+    @Override
+    public boolean createPorts(Iterable<VpnPort> vpnPorts) {
+        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
+        for (VpnPort vpnPort : vpnPorts) {
+            log.info(VPN_PORT_ID, vpnPort.id().toString());
+            vpnPortStore.put(vpnPort.id(), vpnPort);
+            if (!vpnPortStore.containsKey(vpnPort.id())) {
+                log.info(VPN_PORT_CREATION_FAILED, vpnPort.id().toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_SET,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePorts(Iterable<VpnPort> vpnPorts) {
+        checkNotNull(vpnPorts, VPN_PORT_NOT_NULL);
+        for (VpnPort vpnPort : vpnPorts) {
+            if (!vpnPortStore.containsKey(vpnPort.id())) {
+                log.info(VPN_PORT_IS_NOT_EXIST, vpnPort.id().toString());
+                return false;
+            }
+            vpnPortStore.put(vpnPort.id(), vpnPort);
+            if (!vpnPort.equals(vpnPortStore.get(vpnPort.id()))) {
+                log.info(VPN_PORT_UPDATE_FAILED, vpnPort.id().toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_UPDATE,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removePorts(Iterable<VpnPortId> vpnPortIds) {
+        checkNotNull(vpnPortIds, VPN_PORT_NOT_NULL);
+        for (VpnPortId vpnPortid : vpnPortIds) {
+            VpnPort vpnPort = vpnPortStore.get(vpnPortid);
+            vpnPortStore.remove(vpnPortid);
+            if (vpnPortStore.containsKey(vpnPortid)) {
+                log.info(VPN_PORT_DELETE_FAILED, vpnPortid.toString());
+                return false;
+            }
+            notifyListeners(new VpnPortEvent(VpnPortEvent.Type.VPN_PORT_DELETE,
+                                             vpnPort));
+        }
+        return true;
+    }
+
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<VpnPort> vpnPorts;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                VpnPortId vpnPortId
+                        = VpnPortId.vpnPortId(list[list.length - 1]);
+                Set<VpnPortId> vpnPortIds = Sets.newHashSet(vpnPortId);
+                removePorts(vpnPortIds);
+                // After removing vpn port and also remove virtual port from vtn
+                VirtualPortId virtualPortId
+                        = VirtualPortId.portId(list[list.length - 1]);
+                Set<VirtualPortId> virtualPortIds
+                        = Sets.newHashSet(virtualPortId);
+                virtualPortService.removePorts(virtualPortIds);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnPorts = changeJsonToSub(value);
+                createPorts(vpnPorts);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                vpnPorts = changeJsonToSub(value);
+                updatePorts(vpnPorts);
+                break;
+            default:
+                log.info("Invalid action is received while processing VPN " +
+                                 "port configuration");
+        }
+    }
+
+    /**
+     * Creates dummy gluon network to the VTN.
+     *
+     * @param state        the base port state
+     * @param adminStateUp the base port admin status
+     * @param tenantID     the base port tenant ID
+     */
+    private void createDummyGluonNetwork(boolean adminStateUp, String state,
+                                         TenantId tenantID) {
+        String id = "11111111-1111-1111-1111-111111111111";
+        String name = "GluonNetwork";
+        String segmentationID = "50";
+        String physicalNetwork = "None";
+
+        TenantNetwork network = new DefaultTenantNetwork(TenantNetworkId.networkId(id), name,
+                                                         adminStateUp,
+                                                         TenantNetwork.State.valueOf(state),
+                                                         false, tenantID,
+                                                         false,
+                                                         TenantNetwork.Type.LOCAL,
+                                                         PhysicalNetwork.physicalNetwork(physicalNetwork),
+                                                         SegmentationId.segmentationId(segmentationID));
+
+        Set<TenantNetwork> networksSet = Sets.newHashSet(network);
+        tenantNetworkService.createNetworks(networksSet);
+    }
+
+
+    /**
+     * Creates dummy gluon subnet to the VTN.
+     *
+     * @param tenantId the base port tenant ID
+     */
+    public void createDummySubnet(TenantId tenantId) {
+        String id = "22222222-2222-2222-2222-222222222222";
+        String subnetName = "GluonSubnet";
+        String cidr = "0.0.0.0/0";
+        String gatewayIp = "0.0.0.0";
+        Set<HostRoute> hostRoutes = Sets.newHashSet();
+        String ipV6AddressMode = null;
+        String ipV6RaMode = null;
+        TenantNetworkId tenantNetworkId = null;
+        Set<AllocationPool> allocationPools = Sets.newHashSet();
+        Iterable<TenantNetwork> networks
+                = tenantNetworkService.getNetworks();
+
+        for (TenantNetwork tenantNetwork : networks) {
+            if (tenantNetwork.name().equals("GluonNetwork")) {
+                tenantNetworkId = tenantNetwork.id();
+                break;
+            }
+        }
+        Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
+                                          tenantNetworkId,
+                                          tenantId, IpAddress.Version.INET,
+                                          cidr == null ? null : IpPrefix.valueOf(cidr),
+                                          gatewayIp == null ? null : IpAddress.valueOf(gatewayIp),
+                                          false, false, hostRoutes,
+                                          ipV6AddressMode == null ? null : Subnet.Mode.valueOf(ipV6AddressMode),
+                                          ipV6RaMode == null ? null : Subnet.Mode.valueOf(ipV6RaMode),
+                                          allocationPools);
+
+        Set<Subnet> subnetsSet = Sets.newHashSet(subnet);
+        subnetService.createSubnets(subnetsSet);
+    }
+
+    /**
+     * Returns a collection of vpnPort from subnetNodes.
+     *
+     * @param vpnPortNodes the vpnPort json node
+     * @return list of vpnports
+     */
+    private Collection<VpnPort> changeJsonToSub(JsonNode vpnPortNodes) {
+        checkNotNull(vpnPortNodes, JSON_NOT_NULL);
+        Map<VpnPortId, VpnPort> vpnPortMap = new HashMap<>();
+        String interfaceId = vpnPortNodes.get(INTERFACE_ID).asText();
+        VpnPortId vpnPortId = VpnPortId.vpnPortId(interfaceId);
+        VpnInstanceId vpnInstanceId = VpnInstanceId
+                .vpnInstanceId(vpnPortNodes.get(VPN_INSTANCE).asText());
+        VpnPort vpnPort = new DefaultVpnPort(vpnPortId, vpnInstanceId);
+        vpnPortMap.put(vpnPortId, vpnPort);
+        // update ip address and tenant network information in vtn
+        TenantNetworkId tenantNetworkId = null;
+        Map<VirtualPortId, VirtualPort> vPortMap = new HashMap<>();
+        BasePortId basePortId = BasePortId.portId(interfaceId);
+        VirtualPortId virtualPortId = VirtualPortId.portId(interfaceId);
+        BasePort bPort = basePortService.getPort(basePortId);
+        if (bPort != null) {
+            FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(basePortId.toString()),
+                                              IpAddress.valueOf(vpnPortNodes
+                                                                        .get("ipaddress").asText()));
+            Set<FixedIp> fixedIps = new HashSet<>();
+            fixedIps.add(fixedIp);
+            Map<String, String> strMap = new HashMap<>();
+            boolean adminStateUp = bPort.adminStateUp();
+            strMap.put("name", bPort.name());
+            strMap.put("deviceOwner", bPort.deviceOwner());
+            strMap.put("bindingVnicType", bPort.bindingVnicType());
+            strMap.put("bindingVifType", bPort.bindingVifType());
+            strMap.put("bindingVifDetails", bPort.bindingVifDetails());
+            String state = bPort.state();
+            MacAddress macAddress = bPort.macAddress();
+            TenantId tenantId = bPort.tenantId();
+            DeviceId deviceId = bPort.deviceId();
+            BindingHostId bindingHostId = bPort.bindingHostId();
+            // Creates Dummy Gluon Network and Subnet
+            createDummyGluonNetwork(adminStateUp, state, tenantId);
+            createDummySubnet(tenantId);
+
+            Iterable<TenantNetwork> networks
+                    = tenantNetworkService.getNetworks();
+
+            for (TenantNetwork tenantNetwork : networks) {
+                if (tenantNetwork.name().equals("GluonNetwork")) {
+                    tenantNetworkId = tenantNetwork.id();
+                    break;
+                }
+            }
+            if (tenantNetworkId != null) {
+
+                DefaultVirtualPort vPort = new DefaultVirtualPort(virtualPortId,
+                                                                  tenantNetworkId,
+                                                                  adminStateUp,
+                                                                  strMap, isState(state),
+                                                                  macAddress, tenantId,
+                                                                  deviceId, fixedIps,
+                                                                  bindingHostId,
+                                                                  null,
+                                                                  null);
+                vPortMap.put(virtualPortId, vPort);
+                Collection<VirtualPort> virtualPorts
+                        = Collections.unmodifiableCollection(vPortMap.values());
+                virtualPortService.createPorts(virtualPorts);
+            }
+        }
+
+        return Collections.unmodifiableCollection(vpnPortMap.values());
+    }
+
+    /**
+     * Returns BasePort State.
+     *
+     * @param state the base port state
+     * @return the basePort state
+     */
+    private VirtualPort.State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return VirtualPort.State.ACTIVE;
+        } else {
+            return VirtualPort.State.DOWN;
+        }
+
+    }
+
+    @Override
+    public void addListener(VpnPortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(VpnPortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.remove(listener);
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event Vpn Port event
+     */
+    private void notifyListeners(VpnPortEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> {
+            listener.event(event);
+        });
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/package-info.java
new file mode 100755
index 0000000..5dc98e9
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/impl/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.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpnport.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/package-info.java
new file mode 100755
index 0000000..aadae58
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/vpnport/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.
+ */
+
+/**
+ * VPN resources that used by evpn.
+ */
+package org.onosproject.evpnopenflow.rsc.vpnport;
diff --git a/apps/evpnopenflow/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/evpnopenflow/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100755
index 0000000..bb55858
--- /dev/null
+++ b/apps/evpnopenflow/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ Copyright 2017-present 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.
+  -->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.evpnopenflow.rsc.cli.EvpnPublicRouteListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.evpnopenflow.rsc.cli.EvpnPrivateRouteListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.evpnopenflow.rsc.cli.VpnPortListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.evpnopenflow.rsc.cli.VpnInstListCommand"/>
+        </command>
+    </command-bundle>
+</blueprint>
diff --git a/apps/pom.xml b/apps/pom.xml
index 3351e39..bdefb5e 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -90,6 +90,7 @@
         <module>openroadm</module>
         <module>netconf/client</module>
 	<module>gluon</module>
+        <module>evpnopenflow</module>
     </modules>
 
     <properties>
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/EvpnRoute.java b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/EvpnRoute.java
index 06ab18a..555634e 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/EvpnRoute.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/EvpnRoute.java
@@ -62,7 +62,6 @@
      * @param source       route source
      * @param prefixMac    mac address
      * @param prefix       ip address
-     * @param prefix
      * @param nextHop      evpn nexthop
      * @param rd           route distinguisher
      * @param importRtList import route targets
@@ -104,7 +103,6 @@
      * @param importRtList import route targets
      * @param exportRtList export route targets
      * @param labelToInt   evpn route label
-     * @param prefix
      */
     public EvpnRoute(Source source,
                      MacAddress prefixMac,
diff --git a/modules.defs b/modules.defs
index 350fc38..616bf2b 100644
--- a/modules.defs
+++ b/modules.defs
@@ -209,6 +209,7 @@
     '//apps/openroadm:onos-apps-openroadm-oar',
     '//apps/artemis:onos-apps-artemis-oar',
     '//apps/gluon:onos-apps-gluon-oar',
+    '//apps/evpnopenflow:onos-apps-evpnopenflow-oar',
 ]
 
 PROTOCOL_APPS = [